題目鏈接:https://codeforces.com/gym/102394
設S[i]表示前i個位置放了i個燈泡,那麼就有這麼一些關係,0 <= S[i] - S[i-1] <= 1,S[Ri] - S[Li-1] >= Ki,S[n] - (S[Ri] - S[Li-1]) >= Ki
由於第三個式子有三個未知數,又S[n]具有單調性質,所以二分S[n]使得第三個式子變成兩個而知數,同時又有
x<=S[n]<=x,將這些關係利用差分約束建立圖,然後跑最短路看是否有解
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef pair <int,int> pa;
const int mx = 6e3 + 10;
int n,m1,m2;
int dis[mx];
int cnt[mx];
vector <pa> g[mx];
bool vis[mx];
struct node {
int l,r;
int k;
}s[mx];
bool spfa (int mid) {
memset(dis,inf,sizeof(int)*(n+2));
memset(cnt,0,sizeof(int)*(n+2));
memset(vis,0,n+2);
dis[0] = 0, cnt[0]++;
queue <int> q;
q.push(0);
int limit = n;
while (!q.empty()) {
int u = q.front();
q.pop();
vis[u] = 0;
for (pa now:g[u]) {
int v = now.first;
int w = now.second;
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
if (dis[v] < 0) return 0;
if (!vis[v]) {
vis[v] = 1;
if (++cnt[v] > limit) return 0;
q.push(v);
}
}
}
}
return 1;
}
bool check(int mid) {
for (int i=0;i<=n;i++)
g[i].clear();
for (int i=0;i<n;i++)
g[i].push_back(pa(i+1,1));
for (int i=1;i<=n;i++)
g[i].push_back(pa(i-1,0));
for (int i=1;i<=m1;i++)
g[s[i].r].push_back(pa(s[i].l-1,-s[i].k));
for (int i=m1+1;i<=m1+m2;i++)
g[s[i].l-1].push_back(pa(s[i].r,mid-s[i].k));
g[0].push_back(pa(n,mid));
g[n].push_back(pa(0,-mid));
return spfa(mid);
}
int main() {
int t;
scanf("%d",&t);
while (t--) {
scanf("%d%d%d",&n,&m1,&m2);
for (int i=1;i<=m1+m2;i++) {
scanf("%d%d%d",&s[i].l,&s[i].r,&s[i].k);
}
int l = 0, r = n;
while (l < r) {
int mid = l + r >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
printf("%d\n",l);
}
return 0;
}
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef pair <int,int> pa;
typedef long long ll;
const int mx = 1<<18;
const int mod = 1e8 + 7;
int n,m;
ll bit_val;
int dp[mx][20][20];
pa sp[mx];
void global_init() {
for (int i=1;i<=n;i++) {
for (int j=0;j<=m;j++){
for (int k=0;k<=m;k++)
dp[i][j][k] = 0;
}
}
}
int get_lcp(int u,int v) {
for (int i=m-1;i>=0;i--) {
bool val1 = u&(1<<i);
bool val2 = v&(1<<i);
if (val1^val2) return m - (i+1);
}
return m;
}
int main() {
int t;scanf("%d",&t);
while (t--) {
scanf("%d%d",&m,&n);
global_init();
int u,v;
for (int i=1;i<=n;i++) {
scanf("%d%d",&u,&v);
sp[i] = pa(u,v);
}
for (int i=0;i<=sp[1].se;i++) {
u = get_lcp(i,sp[1].se+1);
v = get_lcp(i,sp[1].se);
dp[1][u][v] = (dp[1][u][v] + i) % mod;;
}
for (int i=2;i<=n;i++) {
for (int j=sp[i].fi;j<=sp[i].se;j++) {
int lv = get_lcp(j,sp[i].fi);
int rv = get_lcp(j,sp[i].fi-1);
int nlv = get_lcp(j,sp[i].se+1);
int nrv = get_lcp(j,sp[i].se);
for (int k=0;k<=lv;k++) {
for (int q=rv;q<=m;q++) if(dp[i-1][k][q]){
dp[i][nlv][nrv] += 1ll*j*dp[i-1][k][q]%mod;
dp[i][nlv][nrv] %= mod;
}
}
}
}
ll ans = 0;
for (int i=0;i<=m;i++) {
for (int j=0;j<=m;j++)
ans = (ans + dp[n][i][j])%mod;
}
printf("%lld\n",ans);
}
return 0;
}
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef pair <int,int> pa;
typedef long long ll;
const int mx = 1e5 + 10;
const int mod = 1e9 + 7;
int n,m;
int a[mx];
int main() {
int t;scanf("%d",&t);
while (t--) {
scanf("%d",&n);
for (int i=1;i<=n;i++) {
scanf("%d",a+i);
}
ll ans = 1;
int cnt = 0;
if (a[1] != 0 || a[n] != n-1) ans = 0;
for (int i=2;i<=n;i++) {
if (a[i]<a[i-1]) ans = 0;
if (a[i]==a[i-1]) {
ans = ans*(cnt--)%mod;
} else {
ans = ans*2%mod;
cnt += a[i] - a[i-1] - 1;
}
}
printf("%lld\n",ans);
}
return 0;
}