T1
先不写题解了,可以参考这里。
主要就是图是二分图的充要条件是没有基环,然后判断几种情况即可。
#include<bits/stdc++.h>
#define N 5000005
using namespace std;
int n,m,t=1;
int dep[N],vis[N],odd[N],even[N],ans[N];
int first[N],v[N<<1],nxt[N<<1];
struct edge{int u,v,odd,even,flag;}e[N];
int in(){
int x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=((x+(x<<2))<<1)+(c^'0'),c=getchar();
return x;
}
void out(int x){
if(x>9) out(x/10);
putchar(x%10+'0');
}
void add(int x,int y){
nxt[++t]=first[x],first[x]=t,v[t]=y;
}
void dfs1(int x){
vis[x]=1;
for(int i=first[x];i;i=nxt[i]){
int to=v[i];
if(vis[to]) continue;
dep[to]=dep[x]+1,e[i/2].flag=1,dfs1(to);
}
}
void dfs2(int x){
vis[x]=1;
for(int i=first[x];i;i=nxt[i]){
int to=v[i];
if(vis[to]) continue;
dfs2(to),even[x]+=even[to],odd[x]+=odd[to];
e[i/2].even=even[to],e[i/2].odd=odd[to];
}
}
int main(){
n=in(),m=in();
for(int i=1;i<=m;++i){
e[i].u=in(),e[i].v=in();
add(e[i].u,e[i].v),add(e[i].v,e[i].u);
}
for(int i=1;i<=n;++i)
if(!vis[i]) dfs1(i);
int cnt=0;
for(int i=1;i<=m;++i){
if(e[i].flag) continue;
int u=e[i].u,v=e[i].v;
if(dep[u]>dep[v]) swap(u,v);
if((dep[v]-dep[u])&1) even[v]++,even[u]--;
else odd[v]++,odd[u]--,cnt++,e[i].odd++;
}
if(!cnt){
out(m),putchar('\n');
for(int i=1;i<=m;++i) out(i),putchar(' ');
return 0;
}
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;++i)
if(!vis[i]) dfs2(i);
int tot=0;
for(int i=1;i<=m;++i){
if(e[i].flag){
if(e[i].odd==cnt&&!e[i].even) ans[++tot]=i;
}
else if(e[i].odd&&cnt==1) ans[++tot]=i;
}
out(tot),putchar('\n');
for(int i=1;i<=tot;++i) out(ans[i]),putchar(' ');
return 0;
}
T2
原题:[BZOJ 3682]Phorni。
法 1 1 1:
我们可以直接用线段树维护大小关系,在合并区间的时候二分 + + + 哈希判断大小关系即可。
时间复杂度 O ( n log 2 n ) O(n\log^2n) O(nlog2n),考试数据比较强只有 10 10 10 分。
法 2 2 2:
这是后缀平衡树的模板题。
相当于是建一颗平衡树,每个节点代表一个后缀,相当于是在平衡树上维护后缀的偏序关系。
有关后缀平衡树我就不都说了,能够 O ( 1 ) O(1) O(1) 比较的标号法挺强大的。可以看看这篇博客。
代码实现就用的替罪羊 + + + 线段树。
时间复杂度 O ( n log n ) O(n\log n) O(nlogn)。
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5,M=9e5+5;
char S[M],op[5];
int n,m,len,P[N];
namespace Scapegoat{
double L[M],R[M],alpha=0.75;
int root,tot,*bad,lc[M],rc[M],Size[M],order[M];
double val(int x) {return (!x)?-1e18:L[x]+R[x];}
bool comp(int x,int y) {return (S[x]<S[y])||(S[x]==S[y]&&val(x-1)<val(y-1));}
void ins(int &u,int x,double l,double r){
if(!u) {u=x,L[u]=l,R[u]=r,Size[u]=1;return;}
double mid=(l+r)/2;++Size[u];
if(comp(u,x)){
ins(rc[u],x,mid,r);
if(Size[rc[u]]>alpha*Size[u]) bad=&u;
}
else{
ins(lc[u],x,l,mid);
if(Size[lc[u]]>alpha*Size[u]) bad=&u;
}
}
void inorder(int x){
if(lc[x]) inorder(lc[x]);
order[++tot]=x;
if(rc[x]) inorder(rc[x]);
}
int build(int l,int r,double vl,double vr){
if(l>r) return 0;
int mid=(l+r)>>1;double Mid=(vl+vr)/2;
int u=order[mid];L[u]=vl,R[u]=vr,Size[u]=r-l+1;
lc[u]=build(l,mid-1,vl,Mid);
rc[u]=build(mid+1,r,Mid,vr);
return u;
}
void rebuild(int &k){
tot=0,inorder(k);
k=build(1,tot,L[k],R[k]);
}
void Insert(int i){
bad=NULL,ins(root,i,-1e9,1e9);
if(bad!=NULL) rebuild(*bad);
}
}
using namespace Scapegoat;
namespace Segment{
int mn[N<<2];
int Min(int x,int y) {return (P[x]!=P[y]?val(P[x])<val(P[y]):x<y)?x:y;}
#define mid ((l+r)>>1)
void build(int root,int l,int r){
if(l==r) {mn[root]=l;return;}
build(root<<1,l,mid),build(root<<1|1,mid+1,r);
mn[root]=Min(mn[root<<1],mn[root<<1|1]);
}
void Modify(int root,int l,int r,int x){
if(l==r) {mn[root]=x;return;}
if(x<=mid) Modify(root<<1,l,mid,x);
else Modify(root<<1|1,mid+1,r,x);
mn[root]=Min(mn[root<<1],mn[root<<1|1]);
}
int Query(int root,int l,int r,int x,int y){
if(l>=x&&r<=y) return mn[root];
if(y<=mid) return Query(root<<1,l,mid,x,y);
if(x> mid) return Query(root<<1|1,mid+1,r,x,y);
return Min(Query(root<<1,l,mid,x,y),Query(root<<1|1,mid+1,r,x,y));
}
#undef mid
}
using namespace Segment;
int main(){
scanf("%d%d%d%s",&n,&m,&len,S+1);
reverse(S+1,S+len+1);
for(int i=1;i<=len;++i) Insert(i);
for(int i=1;i<=n;++i) scanf("%d",&P[i]);
build(1,1,n);
int x,pos,l,r,last=0;
while(m--){
scanf("%s",op);
if(op[0]=='I') scanf("%d",&x),x^=last,S[++len]=x+'a',Insert(len);
else if(op[0]=='C') scanf("%d%d",&x,&pos),P[x]=pos,Modify(1,1,n,x);
else scanf("%d%d",&l,&r),printf("%d\n",last=Query(1,1,n,l,r));
}
return 0;
}
T3
原题:[Codeforces 768G]The Winds of Winter 。
还没写。
大佬博客。