The 2020 ICPC Asia Macau Regional Contest
题解:
https://files.cnblogs.com/files/clrs97/2020icpc-macau-analyze.zip
Code:
A. Accelerator
#include<cstdio>
#include<vector>
using namespace std;
typedef long long ll;
typedef vector<int>V;
const int N=1048576,K=19,P=998244353,G=3;
int T,n,m,i,k,a[N],fac[N+10],A[N+10],B[N+10],g[K+1],ng[K+1],inv[N+10];
inline int po(int a,int b){int t=1;for(;b;b>>=1,a=(ll)a*a%P)if(b&1)t=(ll)t*a%P;return t;}
inline void NTT(int*a,int n,int t){
for(int i=1,j=0;i<n-1;i++){
for(int s=n;j^=s>>=1,~j&s;);
if(i<j){int k=a[i];a[i]=a[j];a[j]=k;}
}
for(int d=0;(1<<d)<n;d++){
int m=1<<d,m2=m<<1,_w=t==1?g[d]:ng[d];
for(int i=0;i<n;i+=m2)for(int w=1,j=0;j<m;j++){
int&A=a[i+j+m],&B=a[i+j],t=(ll)w*A%P;
A=B-t;if(A<0)A+=P;
B=B+t;if(B>=P)B-=P;
w=(ll)w*_w%P;
}
}
if(t==-1)for(int i=0,j=inv[n];i<n;i++)a[i]=(ll)a[i]*j%P;
}
V solve(int l,int r){
if(l==r){
V t;
t.push_back(1);
t.push_back(a[l]);
return t;
}
int mid=(l+r)>>1,k=1,i;
V a=solve(l,mid),b=solve(mid+1,r),t;
for(;k<=r-l+1;k<<=1);
for(i=0;i<=mid-l+1;i++)A[i]=a[i];
for(i=mid-l+2;i<k;i++)A[i]=0;
for(i=0;i<=r-mid;i++)B[i]=b[i];
for(i=r-mid+1;i<k;i++)B[i]=0;
NTT(A,k,1),NTT(B,k,1);
for(i=0;i<k;i++)A[i]=1LL*A[i]*B[i]%P;
NTT(A,k,-1);
for(i=0;i<=r-l+1;i++)t.push_back(A[i]);
return t;
}
int main(){
for(g[K]=po(G,(P-1)/N),ng[K]=po(g[K],P-2),i=K-1;~i;i--)g[i]=(ll)g[i+1]*g[i+1]%P,ng[i]=(ll)ng[i+1]*ng[i+1]%P;
for(inv[1]=1,i=2;i<N;i++)inv[i]=(ll)(P-inv[P%i])*(P/i)%P;
for(fac[0]=i=1;i<N;i++)fac[i]=1LL*fac[i-1]*i%P;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
V t=solve(1,n);
int ans=0;
for(i=1;i<=n;i++)ans=(1LL*t[i]*fac[i]%P*fac[n-i]+ans)%P;
ans=1LL*ans*po(fac[n],P-2)%P;
printf("%d\n",ans);
}
}
B. Boring Problem
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=105,M=10005,K=26,P=1000000007;
char s[M];
int n,m,S,i,j,k,deg,x,y,A,B,each[K],ieach[K];
int tot,son[M][K],dep[M],fail[M],g[M][K],q[M];
int cnt,ce,f[M][N],a[N][N],ans[N],e[M];
inline int po(int a,int b){int t=1;for(;b;b>>=1,a=1LL*a*a%P)if(b&1)t=1LL*t*a%P;return t;}
inline void ins(){
scanf("%s",s+1);
for(int i=1,x=0,w;i<=m;i++){
if(!son[x][w=s[i]-'a'])son[x][w]=++tot;
x=son[x][w];
dep[x]=i;
}
}
void make(){
int h=1,t=0,i,j,x;
fail[0]=-1;
for(i=0;i<=tot;i++)for(j=0;j<S;j++)g[i][j]=son[i][j];
for(i=0;i<S;i++)if(g[0][i])q[++t]=g[0][i];
while(h<=t){
x=q[h++];
for(i=0;i<S;i++){
if(g[x][i])fail[g[x][i]]=g[fail[x]][i],q[++t]=g[x][i];
else g[x][i]=g[fail[x]][i];
}
}
}
void gauss(){
int i,j,k,inv,t;
for(i=1;i<=cnt;i++)for(j=1;j<=cnt;j++)a[i][j]=(a[i][j]%P+P)%P;
for(i=1;i<=cnt;i++)a[i][0]=(P-a[i][0])%P;
for(i=1;i<=cnt;i++){
for(j=i;j<=cnt;j++)if(a[j][i])break;
for(k=0;k<=cnt;k++)swap(a[i][k],a[j][k]);
inv=po(a[i][i],P-2);
for(j=i+1;j<=cnt;j++){
t=1LL*a[j][i]*inv%P;
for(k=0;k<=cnt;k++)a[j][k]=(a[j][k]-1LL*t*a[i][k])%P;
}
}
for(i=cnt;i;i--){
t=a[i][0];
for(j=cnt;j>i;j--)t=(t-1LL*a[i][j]*ans[j])%P;
ans[i]=1LL*t*po(a[i][i],P-2)%P;
}
}
int main(){
scanf("%d%d%d",&n,&m,&S);
for(i=0;i<S;i++){
scanf("%d",&x);
each[i]=1LL*x*po(100,P-2)%P;
ieach[i]=po(each[i],P-2);
}
while(n--)ins();
make();
cnt=1;
f[0][1]=1;
for(i=0;i<=tot;i++){
deg=0;
for(j=0;j<S;j++)if(son[i][j]){
deg++;
if(deg>1){
cnt++;
f[son[i][j]][cnt]=1;
}
}
}
for(i=0;i<=tot;i++){
x=q[i];
deg=0;
for(j=0;j<S;j++)if(son[x][j]){
deg++;
if(deg==1)A=son[x][j],B=j;
}
if(deg){
//e[x]=sum(e[g[x][i]]*each[i])+1
//e[A]*each[B]=e[x]-1-sum(e[g[x]][i]*each[i])
for(j=0;j<=cnt;j++)f[A][j]=f[x][j];
f[A][0]--;
for(j=0;j<S;j++)if(j!=B){
y=g[x][j];
for(k=0;k<=cnt;k++)f[A][k]=(f[A][k]-1LL*f[y][k]*each[j])%P;
}
for(j=0;j<=cnt;j++)f[A][j]=1LL*f[A][j]*ieach[B]%P;
}
}
for(i=0;i<=tot;i++)if(dep[i]==m){
ce++;
for(j=0;j<=cnt;j++)a[ce][j]=f[i][j];
}
gauss();
for(i=0;i<=tot;i++){
k=f[i][0];
for(j=1;j<=cnt;j++)k=(k+1LL*f[i][j]*ans[j])%P;
e[i]=(k%P+P)%P;
}
scanf("%s",s);
for(x=i=0;s[i];i++){
if(dep[x]<m)x=g[x][s[i]-'a'];
printf("%d\n",e[x]+i+1);
}
}
C. Club Assignment
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100010,M=N*31,K=29;
int Case,n,i,q[N],_q[N],son[M][2],val[M],tot,g[N],v[N<<1],nxt[N<<1],ed;
int c0,c1,p0[N],p1[N],col[N];
int a[N],ans;
inline void add(int x,int y){
v[++ed]=y;nxt[ed]=g[x];g[x]=ed;
v[++ed]=x;nxt[ed]=g[y];g[y]=ed;
}
inline void ins(int p,int t){
int o=K,x=0;
for(;~o;o--){
int w=p>>o&1;
if(!son[x][w])son[x][w]=++tot;
x=son[x][w];
}
val[x]=t;
}
inline int ask(int p){
int o=K,x=0;
for(;~o;o--){
int w=p>>o&1;
if(son[x][w])x=son[x][w];else x=son[x][w^1];
}
return val[x];
}
inline void clr(){
for(int i=0;i<=tot;i++)son[i][0]=son[i][1]=val[i]=0;
tot=0;
}
void solve(int o,int l,int r){
if(l>r)return;
if(o<0){
for(int i=l+1;i<=r;i++)add(q[i],q[l]);
return;
}
int L=l-1,R=r+1;
for(int i=l;i<=r;i++)if(a[q[i]]>>o&1)_q[++L]=q[i];else _q[--R]=q[i];
for(int i=l;i<=r;i++)q[i]=_q[i];
solve(o-1,l,L),solve(o-1,R,r);
if(l>L||R>r)return;
for(int i=l;i<=L;i++)ins(a[q[i]],q[i]);
int ret=~0U>>1,x=0,y=0;
for(int i=R;i<=r;i++){
int j=ask(a[q[i]]),tmp=a[q[i]]^a[j];
if(tmp<ret)ret=tmp,x=q[i],y=j;
}
clr();
add(x,y);
}
void dfs(int x,int y,int z){
col[x]=z;
if(z==0)p0[++c0]=x;else p1[++c1]=x;
for(int i=g[x];i;i=nxt[i])if(v[i]!=y)dfs(v[i],x,z^1);
}
inline void cal(int n,int*q){
for(int i=1;i<=n;i++){
if(i>1)ans=min(ans,a[q[i]]^a[ask(a[q[i]])]);
ins(a[q[i]],q[i]);
}
clr();
}
int main(){
scanf("%d",&Case);
while(Case--){
scanf("%d",&n);//n>=3
for(ed=c0=c1=i=0;i<=n;i++)g[i]=0;
for(i=1;i<=n;i++)scanf("%d",&a[i]),q[i]=i;//[1,1e9]
solve(K,1,n);
dfs(1,0,0);
ans=~0U>>1;
cal(c0,p0);
cal(c1,p1);
printf("%d\n",ans);
for(i=1;i<=n;i++)putchar(col[i]+'1');
puts("");
}
}
D. Artifacts
#include<cstdio>
#include<cstring>
int i,j,n;
char s[111111];
double atk=0,atkrate=0,critdmg=50,critrate=5,e;
int main(){
for(i=0;i<25;i++){
fgets(s+1,10000,stdin);
n=strlen(s+1);
double tmp=0,base=0.1;
bool flag=0;
for(j=1;j<=n;j++){
if(s[j]>='0'&&s[j]<='9'){
if(flag==0)tmp=tmp*10+s[j]-'0';
else{
tmp+=base*(s[j]-'0');
base*=0.1;
}
}else if(s[j]=='.'){
flag=1;
}
}
if(s[1]=='A'&&s[2]=='T'&&s[3]=='K'){
if(s[4]==' '){
atkrate+=tmp;
}else{
atk+=tmp;
}
}
if(s[1]=='C'&&s[2]=='r'&&s[3]=='i'&&s[4]=='t'){
if(s[6]=='R'){
critrate+=tmp;
}else{
critdmg+=tmp;
}
}
}
atk=1500*(1+atkrate*0.01)+atk;
critrate*=0.01;
critdmg*=0.01;
if(critrate>1)critrate=1;
e=atk*(1-critrate)+atk*(1+critdmg)*critrate;
printf("%.15f",e);
}
E. Mountain
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long double ld;
const int N=105;
int n,m,all,W,H,o,i,j,S,T,h[N],q[N];
ld f[2][(1<<((5*2)-1))+1][N],tmp;
inline void up(ld&a,ld b){a<b?(a=b):0;}
inline ld solve(int A,int B,int K){
if(K<=0)return 0;
if(K<=A)return K;
if(K>=B)return (A+B)*0.5;
return (A+B)*0.5-(0.5*(B-K)*(B-K))/(B-A);
}
inline ld cal(int x,int S){
int l,r,L,R,cnt,i,j,k,A,B;
l=max(x-W,0);
r=min(x+W,n+1);
ld ret=0;
for(i=l;i<r;i++){
L=max(i-W+1,max(1,x-m));
R=min(i+W,x);
A=h[i],B=h[i+1];
if(A>B)swap(A,B);
cnt=0;
for(j=L;j<=R;j++)if(S>>(x-j)&1)q[++cnt]=h[j];
sort(q+1,q+cnt+1);
for(j=1;j<=cnt;j=k+1){
k=j;
while(k<cnt&&q[k+1]-q[k]<=H*2)k++;
ret+=solve(A,B,q[k]+H)-solve(A,B,q[j]-H);
}
}
return ret;
}
int main(){
scanf("%d%d%d",&n,&W,&H);
for(i=1;i<=n;i++)scanf("%d",&h[i]);
m=W*2-1;
all=(1<<m)-1;
for(i=1;i<=n;i++,o^=1){
for(S=0;S<=all;S++)for(j=0;j<=n;j++)f[o^1][S][j]=0;
for(S=0;S<=all;S++){
T=(S<<1)&all;
tmp=cal(i,S<<1|1)-cal(i,S<<1);
for(j=0;j<=n;j++){
up(f[o^1][T][j],f[o][S][j]);
up(f[o^1][T+1][j+1],f[o][S][j]+tmp);
}
}
}
for(i=1;i<=n;i++){
tmp=0;
for(S=0;S<=all;S++)up(tmp,f[o][S][i]);
printf("%.15f\n",(double)tmp);
}
}
F. Fixing Networks
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
using namespace std;
const int N=200005;
int n,m,D,C,i,j,k;vector<int>g[N];
void NIE(){
puts("No");
exit(0);
}
inline int fix(int x){
while(x<1)x+=m;
while(x>m)x-=m;
return x;
}
int main(){
scanf("%d%d%d",&n,&D,&C);
if(n%2&&D%2)NIE();
if(1LL*C*(D+1)>n)NIE();
if(D==0&&n!=C)NIE();
m=n-(C-1)*(D+1);
//D+1<=n-(C-1)*(D+1)
if(D==1){
if(m!=2)NIE();
g[1].push_back(2);
g[2].push_back(1);
}else{
for(i=1;i<=m;i++){
for(j=1;j<=D/2;j++)g[i].push_back(fix(i-j)),g[i].push_back(fix(i+j));
if(D%2)g[i].push_back(fix(i+m/2));
}
}
for(i=1;i<C;i++){
for(j=1;j<=D+1;j++)for(k=1;k<=D+1;k++)if(j!=k)g[m+j].push_back(m+k);
m+=D+1;
}
puts("Yes");
for(i=1;i<=n;i++){
sort(g[i].begin(),g[i].end());
for(j=0;j<D;j++)printf("%d%c",g[i][j],j<D-1?' ':'\n');
}
}
G. Game on Sequence
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=400005,M=256;
int n,m,i,op,x,a[N],v[M+1],q[M+1],f[M+1];
inline bool cmp(int x,int y){return v[x]>v[y];}
inline bool gao(int x){
if(x!=v[a[x]])return 1;
int i,j;
for(i=0;i<M;i++)q[i]=i;
sort(q,q+M,cmp);
for(i=0;i<M;i++)f[i]=0;
for(i=0;i<M;i++){
for(j=0;j<8;j++)if(f[q[i]^(1<<j)])break;
if(q[i]==a[x])return j<8;
if(j==8)f[q[i]]=1;
}
}
int main(){
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)scanf("%d",&a[i]),v[a[i]]=i;
while(m--){
scanf("%d%d",&op,&x);
if(op==1)a[v[x]=++n]=x;
else puts(gao(x)?"Grammy":"Alice");
}
}
H. Fly Me To The Moon
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
using namespace std;
typedef long long ll;
const int md = 998244353;
inline int add(int x, int y) {
x += y;
if (x >= md) x -= md;
return x;
}
inline void addx(int &x, int y) {
x += y;
if (x >= md) x -= md;
}
inline int sub(int x, int y) {
x -= y;
if (x < 0) x += md;
return x;
}
inline void subx(int &x, int y) {
x -= y;
if (x < 0) x += md;
}
inline int mul(int x, int y) { return 1ull * x * y % md; }
inline int fpow(int x, int y) {
int ans = 1;
while (y) {
if (y & 1) ans = mul(ans, x);
y >>= 1; x = mul(x, x);
}
return ans;
}
vector <int> roots, rev;
void getRevRoot(int base) {
int n = 1 << base;
if ((int)roots.size() == n) return;
roots.resize(n); rev.resize(n);
for (int i = 1; i < n; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (base - 1));
for (int mid = 1; mid < n; mid <<= 1) {
int wn = fpow(3, (md - 1) / (mid << 1));
roots[mid] = 1;
for (int i = 1; i < mid; i++) roots[i + mid] = mul(roots[i + mid - 1], wn);
}
}
void ntt(vector <int> &a, int base) {
int n = 1 << base;
for (int i = 0; i < n; i++) {
if (i < rev[i]) {
swap(a[i], a[rev[i]]);
}
}
for (int mid = 1; mid < 4 && mid < n; mid <<= 1) {
for (int i = 0; i < n; i += (mid << 1)) {
for (int j = 0; j < mid; j++) {
int x = a[i + j], y = mul(a[i + j + mid], roots[mid + j]);
a[i + j] = add(x, y); a[i + j + mid] = sub(x, y);
}
}
}
for (int mid = 4; mid < n; mid <<= 1) {
for (int i = 0; i < n; i += (mid << 1)) {
for (int j = 0; j < mid; j += 4) {
int tmp = mul(a[i + j + mid], roots[mid + j]);
a[i + j + mid] = sub(a[i + j], tmp);
a[i + j] = add(a[i + j], tmp);
tmp = mul(a[i + j + mid + 1], roots[mid + j + 1]);
a[i + j + mid + 1] = sub(a[i + j + 1], tmp);
a[i + j + 1] = add(a[i + j + 1], tmp);
tmp = mul(a[i + j + mid + 2], roots[mid + j + 2]);
a[i + j + mid + 2] = sub(a[i + j + 2], tmp);
a[i + j + 2] = add(a[i + j + 2], tmp);
tmp = mul(a[i + j + mid + 3], roots[mid + j + 3]);
a[i + j + mid + 3] = sub(a[i + j + 3], tmp);
a[i + j + 3] = add(a[i + j + 3], tmp);
}
}
}
}
const ll P = 1ll * md * md;
const int N = 1001 * 1001 + 5, M = 3, U = 1005;
vector <int> F[M], G[M], tmp, ANS;
int n[M], facn[M], nt[N], ways[U][U], suf[N * 2];
int lim, k, dis;
int da[M];
void dfs1(int u) {
if (u == k + 1) {
int id = 0;
for (int i = 1; i <= k; i++) id += da[i] * facn[i - 1];
if (da[1] == 0 && da[2] == 0) tmp[id] = 1;
else tmp[id] = md - suf[da[1]*da[1]+da[2]*da[2]];
return;
}
for (int i = 0; i < n[u]; i++) {
da[u] = i;
dfs1(u + 1);
}
}
void dfs2(int u) {
if (u == k + 1) {
int id = 0;
for (int i = 1; i <= k; i++) id += da[i] * facn[i - 1];
ways[da[1]][da[2]] = ANS[id];
return;
}
for (int i = 0; i < n[u]; i++) {
da[u] = i;
dfs2(u + 1);
}
}
vector <int> mul(vector <int> a, vector <int> b, int need, int ntted = 0, int limit = 0) {
int len = (int)a.size() + (int)b.size() - 1, base = 0;
if (limit) len = limit;
while ((1 << base) < len) ++base;
// cerr << "base = " << base << endl;
getRevRoot(base);
for (int i = 0; i < k; i++) {
F[i].clear(); F[i].resize(1 << base);
if (!ntted) {
G[i].clear(); G[i].resize(1 << base);
}
}
for (int i = 0; i < (int)a.size(); i++) F[nt[i]][i] = a[i];
if (!ntted) {
for (int i = 0; i < (int)b.size(); i++) G[nt[i]][i] = b[i];
}
for (int i = 0; i < k; i++) {
ntt(F[i], base);
if (!ntted) ntt(G[i], base);
}
for (int i = 0; i < (1 << base); i++) {
static ll res[M];
memset(res, 0, sizeof(res));
for (int j = 0; j < k; j++) {
for (int t = 0; t < k; t++) {
// addx(res[(j + t) % k], mul(F[j][i], G[t][i]));
int go = (j + t >= k ? j + t - k : j + t);
res[go] += 1ll * F[j][i] * G[t][i];
if (res[go] >= P) res[go] -= P;
}
}
for (int j = 0; j < k; j++) F[j][i] = res[j] % md;
}
int inv = fpow(1 << base, md - 2);
for (int i = 0; i < k; i++) {
ntt(F[i], base);
reverse(F[i].begin() + 1, F[i].end());
}
vector <int> ans(need);
for (int i = 0; i < need; i++) ans[i] = mul(inv, F[nt[i]][i]);
return ans;
}
vector <int> pinv(vector <int> a, int n) {
a.resize(n);
if (n == 1) {
vector <int> ans(1, fpow(a[0], md - 2));
return ans;
}
vector <int> f0 = pinv(a, (n + 1) >> 1);
vector <int> tmp = mul(a, f0, n, 0, n), ans = f0;
for (int i = 0; i < (int)f0.size(); i++) tmp[i] = 0;
tmp = mul(tmp, f0, n, 1, n); ans.resize(n);
for (int i = (int)f0.size(); i < n; i++) ans[i] = sub(0, tmp[i]);
return ans;
}
namespace DP{
int i,j,f[U];
pair<int,int>e[U];
void gao(int n){
e[0].first=e[0].second=1000;
for(i=1;i<=n;i++)cin>>e[i].first>>e[i].second;
sort(e,e+n+1);
for(i=0;i<=n;i++){
f[i]=ways[e[i].first][e[i].second];
for(j=0;j<i;j++)if(e[j].second<=e[i].second)f[i]=(f[i]-1LL*f[j]*ways[e[i].first-e[j].first][e[i].second-e[j].second])%md;
}
cout<<(f[n]%md+md)%md;
}
}
int main() {
k = 2;
for (int i = 1; i <= k; i++) n[i] = 1001;
int _,__;
cin >> _ >> __;
while(_--){
int x;
cin>>x;
suf[x*x]++;
}
for(int i=N*2-1;i;i--)suf[i-1]+=suf[i];
facn[0] = 1;
for (int i = 1; i <= k; i++) facn[i] = facn[i - 1] * n[i];
lim = facn[k];
tmp.resize(lim);
dfs1(1);
for (int i = 0; i < lim; i++) {
int res = 0;
for (int j = 1; j < k; j++) res += i / facn[j];
nt[i] = res % k;
}
ANS = pinv(tmp, lim);
dfs2(1);
DP::gao(__);
}
I. Nim Cheater
#include<cstdio>
const int N=20005,M=16384,inf=~0U>>1;
int n,m,cur,i,x,y,loc[N<<1],val[N],cost[N],fa[N],g[N],nxt[N],size[N],son[N];
int dp[17][M+1],ans[N],sum[N];
inline void up(int&a,int b){a<b?(a=b):0;}
void dfs(int x){
size[x]=1;
for(int i=g[x];i;i=nxt[i]){
dfs(i);
size[x]+=size[i];
if(size[i]>size[son[x]])son[x]=i;
}
}
void dfs2(int x,int o){
int i,j,A=val[x],B=cost[x];
if(x>1)for(j=0;j<M;j++)if(j<=(j^A)){
int tmp=dp[o][j];
up(dp[o][j],dp[o][j^A]+B);
up(dp[o][j^A],tmp+B);
}
ans[x]=sum[x]-dp[o][0];
for(i=g[x];i;i=nxt[i])if(i!=son[x]){
for(j=0;j<M;j++)dp[o+1][j]=dp[o][j];
dfs2(i,o+1);
}
if(son[x])dfs2(son[x],o);
}
int main(){
scanf("%d",&m);
cur=n=1;
for(i=1;i<=m;i++){
char op[9];
scanf("%s",op);
if(op[0]=='A'){
scanf("%d%d",&x,&y);
n++;
val[n]=x;
cost[n]=y;
fa[n]=cur;
sum[n]=sum[cur]+y;
nxt[n]=g[cur];
g[cur]=n;
cur=n;
}else cur=fa[cur];
loc[i]=cur;
}
dfs(1);
for(i=1;i<M;i++)dp[0][i]=-inf;
dfs2(1,0);
for(i=1;i<=m;i++)printf("%d\n",ans[loc[i]]);
}
J. Jewel Grab
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
const int N=200005,M=524305;
int n,m,i,op,x,y,col[N],val[N],last[N],pre[N],vis[N],w[N],POS;
set<int>T[N];
int v[M],X,Y;ll s[M],ans;
inline void up(int x){
v[x]=max(v[x<<1],v[x<<1|1]);
s[x]=s[x<<1]+s[x<<1|1];
}
void build(int x,int a,int b){
if(a==b){
v[x]=pre[a];
s[x]=val[a];
return;
}
int mid=(a+b)>>1;
build(x<<1,a,mid),build(x<<1|1,mid+1,b);
up(x);
}
void change(int x,int a,int b,int c){
if(a==b){
v[x]=pre[a];
s[x]=val[a];
return;
}
int mid=(a+b)>>1;
if(c<=mid)change(x<<1,a,mid,c);else change(x<<1|1,mid+1,b,c);
up(x);
}
void go(int x,int a,int b,int c){
//printf(">> [%d,%d] v=%d X=%d\n",a,b,v[x],X);
if(c<=a&&v[x]<X){
Y=b;
ans+=s[x];
return;
}
if(a==b)return;
int mid=(a+b)>>1;
if(c<=mid)go(x<<1,a,mid,c);
if(Y>=mid)go(x<<1|1,mid+1,b,c);
}
inline ll query(int x,int k){
int o=x;
ans=0;
POS++;
X=x;
while(k>=0&&o<=n){
Y=o-1;
go(1,1,n,o);//find max that pre<x, if no sol then Y=o-1
//printf("o=%d Y=%d ans=%lld\n",o,Y,ans);
if(Y==n||!k)break;
k--;
o=Y+1;
int C=col[o];
if(vis[C]==POS){
if(w[C]<val[o]){
ans+=val[o]-w[C];
w[C]=val[o];
}
}else{
vis[C]=POS;
w[C]=max(val[pre[o]],val[o]);
ans+=w[C]-val[pre[o]];
}
o++;
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)T[i].insert(0),T[i].insert(n+1);
for(i=1;i<=n;i++){
scanf("%d%d",&col[i],&val[i]);
T[col[i]].insert(i);
pre[i]=last[col[i]];
last[col[i]]=i;
}
build(1,1,n);
while(m--){
scanf("%d%d%d",&op,&x,&y);
if(op==1){
scanf("%d",&val[x]);
set<int>::iterator it=T[col[x]].find(x),j,k;
j=k=it;
j--,k++;
if(*k<=n){
pre[*k]=*j;
change(1,1,n,*k);
}
T[col[x]].erase(x);
T[col[x]=y].insert(x);
j=k=it=T[y].find(x);
j--,k++;
pre[x]=*j;
change(1,1,n,x);
if(*k<=n){
pre[*k]=x;
change(1,1,n,*k);
}
}else printf("%lld\n",query(x,y));
}
}
K. Candy Ads
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef unsigned long long ull;
const int N=50005,M=787,L=2005;
int n,m,cnt,all,W,H,i,j,x,y,q[N<<1],t,f[N<<1];
ull fl[L][M],fr[L][M],f1[L][M],f2[L][M],vis0[M],vis1[M];
vector<int>g[N<<1],h[N<<1];
struct E{int l,r,x,y,t,v;}e[N];
inline bool cmpv(const E&a,const E&b){return a.v<b.v;}
inline bool cmpt(const E&a,const E&b){return a.t<b.t;}
inline void pre(int lim,ull f[][M]){
sort(e,e+n,cmpv);
for(int i=1,j=0,k=0;i<L;i++){
for(int x=0;x<=all;x++)f[i][x]=f[i-1][x];
while(j<n&&e[j].v<=i-lim){
f[i][e[j].t>>6]^=1ULL<<(e[j].t&63);
j++;
}
while(k<n&&e[k].v<=i+lim-1){
f[i][e[k].t>>6]^=1ULL<<(e[k].t&63);
k++;
}
}
}
inline void addedge(int x,int y){
g[x].push_back(y);
h[y].push_back(x);
}
inline bool visit(int x){
if(x<n)return vis0[x>>6]>>(x&63)&1;
x-=n;
return vis1[x>>6]>>(x&63)&1;
}
inline void flip(int x){
if(x<n){
vis0[x>>6]^=1ULL<<(x&63);
return;
}
x-=n;
vis1[x>>6]^=1ULL<<(x&63);
}
void dfs0(int x){
if(!visit(x))return;
flip(x);
for(int i=0;i<g[x].size();i++)dfs0(g[x][i]);
if(x<n){
int L=e[x].l,R=e[x].r,B=e[x].x,C=e[x].y;
for(int i=0;i<=all;i++){
ull S=fl[R][i]&fr[L][i]&f1[B][i]&f2[C][i];
if(i==(x>>6))S^=1ULL<<(x&63);
while(1){
S&=vis1[i];
if(!S)break;
dfs0((i<<6|__builtin_ctzll(S))+n);
}
}
}
q[++t]=x;
}
void dfs1(int x){
if(!visit(x))return;
flip(x);
f[x]=cnt;
for(int i=0;i<h[x].size();i++)dfs1(h[x][i]);
if(x<n)return;
x-=n;
int L=e[x].l,R=e[x].r,B=e[x].x,C=e[x].y;
for(int i=0;i<=all;i++){
ull S=fl[R][i]&fr[L][i]&f1[B][i]&f2[C][i];
if(i==(x>>6))S^=1ULL<<(x&63);
while(1){
S&=vis0[i];
if(!S)break;
dfs1(i<<6|__builtin_ctzll(S));
}
}
}
int main(){
scanf("%d%d%d",&n,&W,&H);
all=(n-1)>>6;
for(i=0;i<n;i++)scanf("%d%d%d%d",&e[i].l,&e[i].r,&e[i].x,&e[i].y),e[i].t=i;
for(i=0;i<n;i++){
fl[e[i].l][i>>6]^=1ULL<<(i&63);
fr[e[i].r][i>>6]^=1ULL<<(i&63);
}
for(i=1;i<L;i++)for(j=0;j<=all;j++)fl[i][j]|=fl[i-1][j];
for(i=L-1;i;i--)for(j=0;j<=all;j++)fr[i-1][j]|=fr[i][j];
for(i=0;i<n;i++)e[i].v=e[i].x;
pre(W,f1);
for(i=0;i<n;i++)e[i].v=e[i].y;
pre(H,f2);
sort(e,e+n,cmpt);
scanf("%d",&m);
while(m--){
scanf("%d%d",&x,&y);
x--,y--;
addedge(x+n,y);
addedge(y+n,x);
}
for(i=0;i<=all;i++)vis0[i]=vis1[i]=0;
for(i=0;i<n;i++)vis0[i>>6]^=1ULL<<(i&63);
for(i=0;i<=all;i++)vis1[i]=vis0[i];
for(i=0;i<n+n;i++)dfs0(i);
for(i=0;i<=all;i++)vis0[i]=vis1[i]=0;
for(i=0;i<n;i++)vis0[i>>6]^=1ULL<<(i&63);
for(i=0;i<=all;i++)vis1[i]=vis0[i];
for(i=t;i;i--)cnt++,dfs1(q[i]);
for(i=0;i<n;i++)if(f[i]==f[i+n])return puts("No"),0;
puts("Yes");
for(i=0;i<n;i++)putchar(f[i]<f[i+n]?'0':'1');
puts("");
}
L. Random Permutation
//n!*n!/n^n
#include<cstdio>
int n,i;double ans;
int main(){
scanf("%d",&n);
ans=1;
for(i=1;i<=n;i++)ans*=i*i,ans/=n;
printf("%.15f",ans);
}

浙公网安备 33010602011771号