B:https://nanti.jisuanke.com/t/40254
做两次插值,可以On得出a[n +1]的一项,然后前缀和,再做插值,针对每次查询,On处理
ll a[maxn];
ll fac[maxn],invv[maxn],suf[maxn],pre[maxn] ;
void Init(){
fac[0] = 1;
fac[1] = 1;
for(int i = 2;i <= 2000;i++) fac[i] = fac[i - 1] * i,fac[i] %= mod;
for(int i = 0;i <= 2000;i++) invv[i] = inv(fac[i]);
return ;
}
ll post[maxn];
ll calc(ll k,ll n){
ll res = 0;
pre[0] = k;/*
for(int i = 1;i <= n;i++) mul2(pre[i],mul1(pre[i - 1],k - i));*/
for(int i = 1;i <= n;i++) pre[i] = pre[i - 1] * (k - i),pre[i] %= mod;
post[n] = k - n;
for(int i = n - 1;i >= 0;i--) post[i] = post[i + 1] * (k - i),post[i] %= mod ;
for(int i = 0;i <= n;i++){
ll num = invv[i] * invv[n - i] % mod;
if((n - i) & 1) num = -num;
if(i - 1 >= 0)
num *= pre[i - 1];num %= mod;
if(i + 1 <= n)
num *= post[1 + i],num %= mod;
num *= a[i],num %= mod;
res += num; res += mod, res %= mod;
}
return res;
}
ll n,k;
int main()
{
Init();
ios; int t,q;cin >> t;while(t--){
cin >> n >> q;
for(int i =0;i <= n;i++) cin >> a[i];
a[n + 1] = calc(n + 1,n);
for(int i = 1;i <= n + 1;i++){
a[i] += a[i - 1];
a[i] %= mod;
}
while(q--){
ll l,r; cin >> l >> r;
ll val1 = calc(r,n + 1);
ll val2 = calc(l - 1,n + 1);
wt((val1 - val2 + mod) % mod);
}
}
return 0;
}
G https://nanti.jisuanke.com/t/40259
把所有的排序一下 ,然后建边,从高度高的指向低的(其实都一样,最后判断的时候修改一下也可以),缩点后,看看哪些点度数为0,他们就可能赢
ll n,k;
struct node{
int id,val;
}g1[maxn],g2[maxn],g3[maxn];
bool cmp(node a,node b) { return a.val < b.val; }
std::vector v[maxn];
int cnt = 0;
int col[maxn],val[maxn];
int tot;
int low[maxn],dfn[maxn],vis[maxn],in[maxn];
stacks;
void tarjan(int u){
low[u] = dfn[u] = ++tot;
vis[u] = 1;s.push(u);
for(auto d:v[u]){
if(!dfn[d]){
tarjan(d);
low[u] = min(low[u],low[d]);
}else if(vis[d]) low[u] = min(dfn[d],low[u]);
}
if(low[u] == dfn[u]){
int x ; cnt++;
do{
x = s.top(); s.pop();vis[x] = 0; col[x] = cnt;
}while(x != u);
}
return ;
}
mapmp;
void create(int x){
for(auto d:v[x]){
int first = col[x],second = col[d];
if(first == second) continue;
if(!mp[P(first,second)]){
mp[P(first,second)] = 1;
in[second]++;
}
}
}
int main()
{ int q;
while(cin >> n >> q){
cnt = 0 ,tot = 0;
for(int i = 1;i <= n;i++) v[i].clear(),vis[i] = 0,in[i] = 0,col[i] = 0;
for(int j = 1;j <= n;j++) scanf("%d",&g1[j].val),g1[j].id = j;
for(int j = 1;j <= n;j++) scanf("%d",&g2[j].val),g2[j].id = j;
for(int j = 1;j <= n;j++) scanf("%d",&g3[j].val),g3[j].id = j;
sort(rg(g1,1,n),cmp);
sort(rg(g2,1,n),cmp);
sort(rg(g3,1,n),cmp);
for(int i = n;i >= 2;i--){
v[g1[i].id] .pb(g1[i - 1].id);
}
for(int i = n;i >= 2;i--){
v[g2[i].id] .pb(g2[i - 1].id);
}
for(int i = n;i >= 2;i--){
v[g3[i].id] .pb(g3[i - 1].id);
}
for(int i = 1;i <= n;i++)
if(!dfn[i])
tarjan(i);
for(int i = 1;i <= n;i++) create(i);
mapm; /*
for(int i = 1;i <= n;i++) cout << in[i] << " " ;
cout << endl;*/
for(int i = 1;i <= n;i++){
if(!in[col[i]]) m[i] = 1;
}
while(q--){
int x;
scanf("%d",&x);
if(m[x]) puts("YES");
else puts("NO");
}
}
return 0;
}