bzoj2002 弹飞绵羊
调了两小时
注释掉的那一句错了
还在调的可以参考一下
#include<cstdio>
#include<algorithm>
#define rep(a,b,c) for (int a=b;a<=c;a++)
using namespace std;
const int N=200010;
struct dat{
dat *f,*s[2];
int sz;
void up(){
sz=s[0]->sz+s[1]->sz+1;
}
}a0[N];
#define isroot(x) (x->f==a0||(x!=x->f->s[0]&&x!=x->f->s[1]))
void rot(dat *x){
dat *y=x->f,*z=y->f;
bool dx=x==y->s[1],dy=y==z->s[1];
x->f=z;
if (!isroot(y)) z->s[dy]=x;
// (z->s[dy]=x)->f=z;
(y->s[dx]=x->s[!dx])->f=y;
(x->s[!dx]=y)->f=x;
y->up(),x->up();
}
void splay(dat *x){
for (;!isroot(x);rot(x)){
dat *y=x->f,*z=y->f;
if (isroot(y)) continue;
bool dx=x==y->s[1],dy=y==z->s[1];
if (dx==dy) rot(y); else rot(x);
}
}
void access(dat *x){
dat *a=a0,*b=x;
for (;b!=a0;a=b,b=b->f)
splay(b),b->s[1]=a,b->up();
splay(x);
}
int n,q,op,x,y;
int main(){
scanf("%d",&n);
rep(i,0,n+1) a0[i]=(dat){a0,{a0,a0},i!=0};
rep(i,1,n){
int k;
scanf("%d",&k);
a0[i].f=a0+min(k+i,n+1);
}
scanf("%d",&q);
while (q--){
scanf("%d%d",&op,&x),++x;
if (op==1){
dat *k=a0+x;
access(k);
printf("%d\n",k->s[0]->sz);
} else {
int y;
scanf("%d",&y);
y+=x;
if (y>n) y=n+1;
dat *dx=a0+x,*dy=a0+y;
access(dx);
dx->s[0]->f=a0;
dx->s[0]=a0;
dx->up();
access(dy);
(dy->s[1]=dx)->f=dy;
dy->up();
}
}
return 0;
}
NOI2014魔法森林
调了四个小时
#include<cstdio>
#include<algorithm>
#define rep(a,b,c) for (int a=b;a<=c;a++)
using namespace std;
const int N=50010,M=100010;
struct edge{int u,v,a,b;}E[M];
bool cmp(edge x,edge y){return x.a<y.a;}
struct dat{
dat *f,*s[2];
int k,mx,rev;
void up(){
mx=max(k,max(s[0]->mx,s[1]->mx));
}
void down(){
if (!rev) return;
rev=0;
s[0]->rev^=1;
s[1]->rev^=1;
swap(s[0],s[1]);
}
}a0[N+M]={{a0,{a0,a0},0,0,0}},*tot=a0;
#define isroot(x) (x->f==a0||(x!=x->f->s[0]&&x!=x->f->s[1]))
void rot(dat *x){
dat *y=x->f,*z=y->f;
z->down(),y->down(),x->down();
bool dx=x==y->s[1],dy=y==z->s[1];
x->f=z;
if (!isroot(y)) z->s[dy]=x;
(y->s[dx]=x->s[!dx])->f=y;
(x->s[!dx]=y)->f=x;
y->up(),x->up();
}
void splay(dat *x){
x->down();
for (;!isroot(x);rot(x)){
dat *y=x->f,*z=y->f;
if (isroot(y)) continue;
z->down(),y->down(),x->down();
bool dx=x==y->s[1],dy=y==z->s[1];
if (dx==dy) rot(y); else rot(x);
}
}
void access(dat *x){
x->down();
dat *a=a0,*b=x;
for (;b!=a0;a=b,b=b->f)
splay(b),b->s[1]=a,b->up();
splay(x);
}
dat *lft(dat *x){
while (x->down(),x->s[0]!=a0) x=x->s[0];
splay(x);
return x;
}
dat *mex(dat *x){
x->down();
if (x->mx==x->s[0]->mx) return mex(x->s[0]);
if (x->mx==x->s[1]->mx) return mex(x->s[1]);
splay(x);
return x;
}
dat *newnode(int k){
*++tot=(dat){a0,a0,a0,k,k,0};
return tot;
}
#define root(x) (access(x),x->rev^=1)
#define link(x,y) (root(x),x->f=y)
void dfs(dat *x){
if (x==a0) return;
x->down();
dfs(x->s[0]);
printf("%d-",x-a0);
dfs(x->s[1]);
}
void print(){
for (dat *x=a0+1;x<=tot;x++)
if (isroot(x)) dfs(x->s[0]),
printf("(%d)-",x-a0),
dfs(x->s[1]),
printf(" -->%d\n",x->f-a0);
puts("--------");
}
void cut(dat *x,dat *y){
// puts("cut");
root(y);
// print();
access(x);
// printf("y=%d\n",y-a0);
// print();
x->s[0]=y->f=a0;
x->up();
// print();
}
int n,m;
void addedge(int u,int v,int k){
dat *x=a0+u,*y=a0+v,*z;
root(x);
// print();
access(y);
if (lft(y)!=x){
z=newnode(k);
link(x,z);
link(y,z);
} else {
// puts("+eg st");
splay(y);
// print();
z=mex(y);
if (z->k<=k){
newnode(233);
return;
}
// cut(z->s[0],z);
// cut(z->s[1],z);
cut(a0+E[z-a0-n].u,z);
cut(a0+E[z-a0-n].v,z);
z=newnode(k);
link(x,z);
link(y,z);
// print();
// puts("+eg ed");
}
}
int getmax(){
dat *x=a0+1,*y=a0+n;
// puts("gmx start");
root(x);
// print();
access(y);
// puts("gmx end");
if (lft(y)!=x) return 1e6;
return x->mx;
}
int main(){
scanf("%d%d",&n,&m);
rep(i,1,n) newnode(0);
rep(i,1,m){
int u,v,c,d;
scanf("%d%d%d%d",&u,&v,&c,&d);
E[i]=(edge){u,v,c,d};
}
sort(E+1,E+1+m,cmp);
int ans=1e6;
rep(i,1,m){
if (E[i].u==E[i].v){
newnode(233);
continue;
}
addedge(E[i].u,E[i].v,E[i].b);
// print();
ans=min(ans,getmax()+E[i].a);
}
printf("%d\n",ans==1e6?-1:ans);
// getchar(),getchar();
return 0;
}
还有个造数据
#include<cstdio>
#include<algorithm>
#define rep(a,b,c) for (int a=b;a<=c;a++)
using namespace std;
int main(){
srand(time(0));
int n=20,m=600;
printf("%d %d\n",n,m);
rep(i,1,m){
int u=rand()%n+1,v=rand()%n+1,k1=rand()%m+1,k2=rand()%m+1;
printf("%d %d %d %d\n",u,v,k1,k2);
}
return 0;
}
如果帮你省了时间就坠吼了T_T
还有道wwt大爷出的题(应该是的)
想做最好先会palindromic tree2333
图转侵删
#include<cstdio>
#include<cstring>
#define rep(a,b,c) for (int a=b;a<=c;a++)
using namespace std;
typedef long long LL;
const int N=100010;
int Str[N<<1],*str=Str+N;
LL ans;
struct dat{
dat *f,*s[2];
LL k,ks,sum,sk,tag;
void operator +=(int x){
tag+=x;
sum+=sk*x;
ks+=k*x;
}
void up(){
sk=k+s[0]->sk+s[1]->sk;
sum=ks+s[0]->sum+s[1]->sum;
}
void down(){
(*s[0])+=tag;
(*s[1])+=tag;
tag=0;
}
}a0[N]={{a0,{a0,a0}}};
void newnode(int x,int k,int f){
a0[x]=(dat){a0+f,a0,a0,k,0,0,k,0};
}
#define isroot(x) (x->f==a0||(x->f->s[0]!=x&&x->f->s[1]!=x))
void rot(dat *x){
dat *y=x->f,*z=y->f;
bool dx=x==y->s[1],dy=y==z->s[1];
x->f=z;
if (!isroot(y)) z->s[dy]=x;
(y->s[dx]=x->s[!dx])->f=y;
(x->s[!dx]=y)->f=x;
y->up(),x->up();
}
void splay(dat *x){
static dat *q[N];
int t=0;
do q[++t]=x,x=x->f; while (!isroot(q[t]));
while (t) q[t--]->down();
for (x=q[1];!isroot(x);rot(x)){
dat *y=x->f,*z=y->f;
if (isroot(y)) continue;
bool dx=x==y->s[1],dy=y==z->s[1];
if (dx==dy) rot(y); else rot(x);
}
}
void access(dat *x){
dat *a=a0,*b=x;
for (;b->f!=a0;a=b,b=b->f)
splay(b),b->s[1]=a,b->up();
splay(x);
}
void add(int x){
dat *t=a0+x;
// while (t){
// t->s+=t->k;
// t=t->f;
// }
access(t);
*t+=1;
}
LL ask(int x){
LL ans=0;
dat *t=a0+x;
// while (t){
// ans+=t->s;
// t=t->f;
// }
access(a0+x);
return (a0+x)->sum;
}
struct p_tree{
int len,cur,tot,l[N],f[N],s[N][26];
void init(){
len=0;
cur=tot=2;
f[2]=f[1]=1;
l[1]=-1;
l[2]=0;
newnode(1,0,0);
newnode(2,0,1);
}
void extend(int c){
while (str[len-cur[l]]!=c) cur=cur[f];
if (!cur[s][c]){
cur[s][c]=++tot;
tot[l]=cur[l]+2;
if (tot[l]==1) tot[f]=2; else {
int k=cur[f];
while (str[len-k[l]]!=c) k=k[f];
tot[f]=k[s][c];
}
newnode(tot,tot[l]-tot[f][l],tot[f]);
}
cur=cur[s][c];
add(cur);
++len;
}
}pt;
int n,tp;
int main(){
memset(Str,-1,sizeof(Str));
pt.init();
scanf("%d%d",&n,&tp);
LL lst=0;
rep(i,1,n){
scanf("%d",str+i);
str[i]^=tp*lst;
pt.extend(str[i]);
printf("%lld\n",lst=(ans+=ask(pt.cur)));
}
return 0;
}
还有bzoj2555,等下写
写完放SAM模板了