link
这题考场上花了不少时间,虽然想的是小题大做维护环的链表但总归正确性是有的,但是有傻逼错误, O ( 1 ) O(1) O(1)的函数我用 O ( n ) O(n) O(n)实现直接起飞,我拍了几百组1000的数据本以为稳了,下次一定要记得造极限数据测下时间
link
这题的两个小结论
于是我们安排两个人,同时从左上角走到右下角,一个能往右就往右,另一个能往下就往下,如果相交就 c n t + + cnt++ cnt++
于是它就是一个很妙的脑筋急转弯结论题
link
部分分什么的蛇皮做法就不细说了,点分治的正解好像没太搞懂,但是LCT的做法是真的妙
还要感谢pb大佬对我这个菜鸡的帮扶
#include
#define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
#define For(i,a,b) for (register int i=(a);i>=(b);i--)
#define mem(i,j) memset(i,j,sizeof(i))
using namespace std;
typedef long long ll;
const int N=2e5+5;
int h,w,n,a[N],b[N],x[N],y[N],tmp[N],ans[N],back[N],mk[N],out[N];
int sb,vis[N];
int v[2005][2005],pos[N];
struct modify
{
int a,b;
}q[N];
bool cmp(const modify x,const modify y) {return x.a<y.a;}
int read()
{
int x=0,f=1;
char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return f*x;
}
int Get_num(int col,int round,int pos)
{
int ret=pos;
int dir;
if ((pos%2==0&&round%2==1)||(pos%2==1&&round%2==0)) dir=-1;
else dir=1;
round%=col*2;
while (round>0)
{
int del,move;
if (dir==1) del=col-ret;
else del=ret-1;
if (dir==1)
{
move=min(round,del);
ret+=move;
round-=move;
round--;
dir*=-1;
}
else
{
move=min(round,del);
ret-=move;
round-=move;
round--;
dir*=-1;
}
}
return ret;
}
void Debug()
{
while (1)
{
int x=read(),y=read(),z=read();
printf("%d\n",Get_num(x,y,z));
}
return;
}
void Solve()
{
FOR(i,1,w) ans[i]=i;
FOR(i,1,n) v[a[i]][b[i]]=1;
FOR(i,1,h)
{
if (i%2==1)
for (int j=1;j<w;j+=2) if (!v[i][j]) swap(ans[j],ans[j+1]);
if (i%2==0)
for (int j=2;j<w;j+=2) if (!v[i][j]) swap(ans[j],ans[j+1]);
}
FOR(i,1,w) pos[ans[i]]=i;
FOR(i,1,w) printf("%d\n",pos[i]);
return;
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("myans.out","w",stdout);
h=read(),w=read(),n=read();
FOR(i,1,n) a[i]=read(),b[i]=read(),q[i]=(modify){a[i],b[i]};
sort(q+1,q+n+1,cmp);
FOR(i,1,n) x[i]=Get_num(w,q[i].a,q[i].b),y[i]=Get_num(w,q[i].a,q[i].b+1);
FOR(i,1,w) tmp[i]=Get_num(w,h,i);
if (n<=2000)
{
Solve();
exit(0);
}
FOR(i,1,n)
{
if (x[i]==y[i]) continue;
if ((!back[x[i]])&&(!back[y[i]]))
{
mk[x[i]]=y[i];
mk[y[i]]=x[i];
back[x[i]]=y[i];
back[y[i]]=x[i];
}
else if (back[x[i]]&&(!back[y[i]]))
{
mk[y[i]]=x[i];
mk[back[x[i]]]=y[i];
back[y[i]]=back[x[i]];
back[x[i]]=y[i];
}
else if (back[y[i]]&&(!back[x[i]]))
{
mk[x[i]]=y[i];
mk[back[y[i]]]=x[i];
back[x[i]]=back[y[i]];
back[y[i]]=x[i];
}
else if (back[x[i]]&&back[y[i]])//problem here
{
int p1=x[i],p2=y[i];
if (mk[p1]==p2&&mk[p2]==p1)
{
mk[p1]=mk[p2]=0;
back[p1]=back[p2]=0;
}
else if (mk[p1]==p2)
{
mk[back[p1]]=p2;
back[p2]=back[p1];
mk[p1]=back[p1]=0;
}
else if (mk[p2]==p1)
{
mk[back[p2]]=p1;
back[p1]=back[p2];
mk[p2]=back[p2]=0;
}
else
{
int t1=back[p2],t2=back[p1];
mk[t1]=p1;
back[p1]=t1;
mk[t2]=p2;
back[p2]=t2;
}
}
}
FOR(i,1,w)
if (back[tmp[i]]) ans[i]=back[tmp[i]];
else ans[i]=tmp[i];
FOR(i,1,w) out[ans[i]]=i;
FOR(i,1,w) vis[out[i]]=1;
FOR(i,1,w) if (!vis[i]) sb=i;
FOR(i,1,w) if (!out[i]) out[i]=sb;
FOR(i,1,w) printf("%d\n",out[i]);
// Debug();
return 0;
}
#include
#define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
using namespace std;
const int N=1e6+5;
const int mod=1e9+7;
int T,n,a[N],b[N],a1,a2,b1,b2,tag,cnt,same;
int read()
{
int x=0,f=1;
char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return f*x;
}
int qpow(int x,int y)
{
int ret=1;
while (y)
{
if (y&1) ret=1LL*ret*x%mod;
y>>=1;
x=1LL*x*x%mod;
}
return ret;
}
int main()
{
T=read();
while (T--)
{
tag=1,cnt=0,same=1;
n=read();
FOR(i,1,n) a[i]=read();
FOR(i,1,n) b[i]=read();
a1=b1=a2=b2=1;
a[1]--;
b[1]--;
FOR(i,1,n*2-2)
{
if (a[a1]&&b1<n) b1++;
else a1++;
if (b[b2]&&a2<n) a2++;
else b2++;
a[a1]--,b[b2]--;
if (a1!=a2||b1!=b2) a[a2]--,b[b1]--,same=0;
else if (!same) cnt++,same=1;
}
FOR(i,1,n) if (a[i]||b[i]) tag=0;
if (!tag) printf("0\n");
else printf("%d\n",qpow(2,cnt));
}
return 0;
}
#include
#define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
using namespace std;
const int N=2e5+5;
int n,m,q,u[N],v[N];
int pre[N],ch[N][2],rev[N];
int query[N],ans[N],val[N],opt[N],now[N],last[N];
//把联通块的信息维护在了原树深度最浅的点的val上
//所以所有破坏树结构的操作(带makeroot) 都要重新调整val的位置
//当然pb大佬教我的不破坏树结构的方法踩了我一百毫秒
int read()
{
int x=0,f=1;
char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return f*x;
}
int nroot(int x) {return ch[pre[x]][0]==x||ch[pre[x]][1]==x;}
void Update_rev(int p) {if (!p) return;swap(ch[p][0],ch[p][1]);rev[p]^=1;return;}
void Push(int p) {if (!rev[p]) return;if (!rev[p]) return;Update_rev(ch[p][0]);Update_rev(ch[p][1]);rev[p]=0;return;}
void Rotate(int x)
{
int y=pre[x],k=(ch[y][0]==x);
ch[y][!k]=ch[x][k];
if (ch[x][k]) pre[ch[x][k]]=y;
if (pre[y]&&nroot(y)) ch[pre[y]][(ch[pre[y]][1]==y)]=x;
pre[x]=pre[y];
pre[y]=x;
ch[x][k]=y;
return;
}
void Pushall(int x)
{
if (nroot(x)) Pushall(pre[x]);
Push(x);
return;
}
void Splay(int x)
{
Pushall(x);
while (nroot(x))
{
int y=pre[x],z=pre[y];
if (nroot(y))
{
if ((ch[z][1]==y)xor(ch[y][1]==x)) Rotate(x);
else Rotate(y);
}
Rotate(x);
}
return;
}
void Access(int x)
{
int y=0;
for (;x;x=pre[y=x])
{
Splay(x);
ch[x][1]=y;
}
return;
}
int Getrt(int x)
{
Access(x);
Splay(x);
while (ch[x][0]) x=ch[x][0];
Splay(x);
return x;
}
void Make_root(int x)
{
int tmpval=val[Getrt(x)];
Access(x);
Splay(x);
Update_rev(x);
val[x]=tmpval;
return;
}
void Link(int u,int v)
{
Make_root(u);
pre[u]=v;
return;
}
void Cut(int u,int v)
{
int tmpval=val[Getrt(u)];
Make_root(u);
Access(v);
Splay(v);
pre[u]=ch[v][0]=0;
val[Getrt(u)]=val[Getrt(v)]=tmpval;
return;
}
int main()
{
n=read(),m=read(),q=read();
FOR(i,1,n-1) u[i]=read(),v[i]=read();
FOR(i,1,m) opt[i]=read();
FOR(i,1,q) query[i]=read();
FOR(i,1,n) val[i]=1;
FOR(i,1,m)
{
if (!now[opt[i]])
{
int v1=val[Getrt(u[opt[i]])],v2=val[Getrt(v[opt[i]])];
Link(u[opt[i]],v[opt[i]]);
val[Getrt(u[opt[i]])]=v1+v2-last[opt[i]];
}
else
{
last[opt[i]]=val[Getrt(u[opt[i]])];
Cut(u[opt[i]],v[opt[i]]);
}
now[opt[i]]^=1;
}
FOR(i,1,q) ans[i]=val[Getrt(query[i])];
FOR(i,1,q) printf("%d\n",ans[i]);
return 0;
}