Problem A: Fairy
Time Limit: 1000 ms Memory Limit: 256 MB
Description
Given n points, without edges to FIG. M (Loop-free), can be removed from one side of the figure, which edge removal enables Q into a bipartite graph in FIG.
Input
Line 1 comprises two integers n, m, respectively, points and edges.
Of 2 ~ m + 1 lines each two numbers x, y, it indicates there is an edge connecting point x, y.
Output
The first line of two integers representing the number of edges can be deleted.
The next line in ascending order of output side can delete numbers.
Sample Input
4 4
1 2
1 3
2 4
3 4
Sample Output
4
1 2 3 4
HINT
10% of the data, n, m <= 10
40% of the data, n, m <= 1000
70% of the data, n, m <= 100000
100% data, n, m <= 2000000
Solution
We use two arrays odd and eve, odd [u] indicates elapsed (u, fa) of this edge odd ring has several, eve European ring is
For the entire chart, if an odd ring are not, then just select which edge is the answer.
If only one side of an odd ring, then all of Europe is not odd ring on the ring is the answer.
If there are multiple odd ring, only after the (u, fa) of this edge ring odd number and the total number of odd and does not ring the same ring through Europe to meet its conditions.
How odd ring and the European Central Statistical do? Consider the differential statistics:
Dfs first ran the entire tree diagram, for those not in the side dfs trees, our statistical difference, as shown:
Then statistics to get. Code is implemented as follows:
#include<bits/stdc++.h>
using namespace std;
struct qwq{
int v;
int nxt;
int id;
}edge[4000001];
int head[4000001];
int cnt=-1;
void add(int u,int v,int id){
edge[++cnt].nxt=head[u];
edge[cnt].v=v;
edge[cnt].id=id;
head[u]=cnt;
}
int tmp1[4000001],tmp2[4000001];
int odd[4000001],eve[4000001];
int fa[4000001],dep[4000001];
bool mk[4000001];
int ans;
int tmp;
int n,m;
void dfs(int u){
for(int i=head[u];~i;i=edge[i].nxt){
int v=edge[i].v;
if(!dep[v]){
fa[v]=u,dep[v]=dep[u]+1;
mk[edge[i].id>m?edge[i].id-m:edge[i].id]=true;
dfs(v);
odd[u]+=odd[v],eve[u]+=eve[v];
}
else if(v!=fa[u]&&dep[v]<dep[u]){
if((dep[u]-dep[v])%2==1){
tmp2[u]++,tmp2[v]--;
}
else {
ans++;
tmp1[u]++,tmp1[v]--;
tmp=edge[i].id>m?edge[i].id-m:edge[i].id;
}
}
}
odd[u]+=tmp1[u],eve[u]+=tmp2[u];
}
int tot;
int anss[4000001];
struct ed{
int u,v;
}e[4000001];
int main(){
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i){
int u,v;
scanf("%d%d",&u,&v);
add(u,v,i),add(v,u,i+m);
e[i].u=u,e[i].v=v;
}
for(int i=1;i<=n;++i){
if(!dep[i]){
dep[i]=1;
dfs(i);
}
}
if(ans==0){
printf("%d\n",m);
for(int i=1;i<=m;++i)printf("%d ",i);
return 0;
}
if(ans==1){
anss[++tot]=tmp;
}
//for(int i=1;i<=n;++i){
// cout<<odd[i]<<" "<<eve[i]<<endl;
//}
for(int i=1;i<=m;++i){
if(mk[i]){
int u;
if(fa[e[i].v]==e[i].u)u=e[i].v;
if(fa[e[i].u]==e[i].v)u=e[i].u;
if(odd[u]==ans&&eve[u]==0){
anss[++tot]=i;
}
}
}
printf("%d\n",tot);
sort(anss+1,anss+tot+1);
for(int i=1;i<=tot;++i)printf("%d ",anss[i]);
}
Problem B: Phorni
Time Limit: 3000 ms Memory Limit: 512 MB
Description
You give a string S, is the initial length len, there is a sequence of n elements P.
Next, the m operation, there are three types, namely:
In front of a character string is added
Modifying a value of the element P
Ask for all i∈ [l, r], such that S [LP [i] + 1..L] i lexicographically smallest (minimum of a plurality of outputs i, L is the current string length)
(By force)
Input
The input common line m + 3.
The first line of three integers n, m, len.
The second behavior initial string S.
Third row, the number n, the P [1] ... p [n].
Subsequently m rows, each row represents an operation.
Addition of the first I c (c xor lastans) +1 lowercase letter string at a position before the most, wherein Q lastans to the last answer to the inquiry, initially 0.
C x pos the P [x] is modified pos.
Q lr presents to ask [l..r] interval.
Output
For each line of output Q asked to indicate the answer.
Sample Input
3 3 5
horni
3 2 5
I 15
C 1 6
Q 1 3
Sample Output
3
HINT
For 10% of the data, 1 <= n <= 100,1 <= m <= 100,1 <= len <= 100,1 <= P [i] <= len.
To 100% of the data, 1 <= n <= 500000,1 <= m <= 800000,1 <= len <= 100000,1 <= P [i] <= len.
I operation, 0 <= c xor lastans <= 25.
Operation C 1 <= x <= n, 1 <= pos <= the current string length.
Q operation 1 <= l, r <= n.
I of the total number of operations of the operation amount 1/5, C, Q the number of operation about 2/5 of the total number of each operation.
Solution
Ah, the suffix balanced tree board questions
We order from short to long for the suffixes
Consider how quickly determine the size of two lexicographical suffix:
If the first letter different from directly determined;
Otherwise, a judgment on the two suffix suffix size.
Because it is inserted from short to long, so the suffix must have been a good deal
If you then add a new suffix, we do not modify the previous order suffix (obviously), it can directly insert
For the tree balanced tree, we set the value for each node val l, r, node weight = (l + r) / 2
Left son l, r is the l, val-1, so as to ensure the sequence preorder increases monotonically
To meet this feature, we must use a balanced tree - the tree in order to achieve a balance weight
So we choose the scapegoat tree. Then for range queries, sets a segment tree on it
#include<bits/stdc++.h>
using namespace std;
int read(){
int num=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch)){
num=num*10+ch-'0';
ch=getchar();
}
return num*f;
}
struct node{
double l,r,val;
int ch[2];
int siz;
}t[1000001];
int tot;
int rt;
char str[1000001];
const double alp=0.75;
void newnode(int x,double l,double r){
t[x].l=l,t[x].r=r;
t[x].val=(l+r)/2;
t[x].siz=1,t[x].ch[0]=t[x].ch[1]=0;
}
void pushup(int x){
t[x].siz=t[t[x].ch[0]].siz+t[t[x].ch[1]].siz+1;
}
bool isbad(int x){
return t[t[x].ch[0]].siz>t[x].siz*alp||t[t[x].ch[1]].siz>t[x].siz*alp;
}
int que[1000001],L;
void dfs(int x){
if(t[x].ch[0])dfs(t[x].ch[0]);
que[++L]=x;
if(t[x].ch[1])dfs(t[x].ch[1]);
}
int build(int l,int r,double x,double y){
if(l>r)return 0;
int mid=(l+r)/2;
int k=que[mid];
newnode(k,x,y);
t[k].ch[0]=build(l,mid-1,x,t[k].val);
t[k].ch[1]=build(mid+1,r,t[k].val,y);
pushup(k);
return k;
}
void rebuild(int &k){
L=0;
dfs(k);
k=build(1,L,t[k].l,t[k].r);
}
int sta[1000001],top;
void Re(){
for(int i=1;i<=top;++i){
if(isbad(sta[i])){
if(i==1)rebuild(rt);
else {
rebuild(t[sta[i-1]].ch[t[sta[i-1]].ch[1]==sta[i]]);
pushup(sta[i-1]);
}
return;
}
}
}
bool cmp(int x,int y){
return str[x]==str[y]?t[x-1].val<t[y-1].val:str[x]<str[y];
}
void ins(int p){
tot++;
if(!rt){
rt=tot;
newnode(tot,1,1e18);
return;
}
top=0;
int k=rt;
while(233){
bool d=cmp(k,p);
sta[++top]=k;
t[k].siz++;
if(!t[k].ch[d]){
t[k].ch[d]=tot;
if(d)newnode(tot,t[k].val,t[k].r);
else newnode(tot,t[k].l,t[k].val);
break;
}
k=t[k].ch[d];
}
Re();
}
int len[1000001];
int minn[4000001];
int pushup(int x,int y){
return t[len[x]].val<=t[len[y]].val?x:y;
}
void Build(int o,int l,int r){
if(l==r){
minn[o]=l;
return;
}
int mid=(l+r)/2;
Build(o*2,l,mid);
Build(o*2+1,mid+1,r);
minn[o]=pushup(minn[o*2],minn[o*2+1]);
}
void update(int o,int l,int r,int pos){
if(l==r){
minn[o]=l;
return;
}
int mid=(l+r)/2;
if(pos<=mid)update(o*2,l,mid,pos);
else update(o*2+1,mid+1,r,pos);
minn[o]=pushup(minn[o*2],minn[o*2+1]);
}
int query(int o,int l,int r,int L,int R){
if(L<=l&&r<=R)return minn[o];
int mid=(l+r)/2;
if(R<=mid)return query(o*2,l,mid,L,R);
if(mid<L)return query(o*2+1,mid+1,r,L,R);
return pushup(query(o*2,l,mid,L,R),query(o*2+1,mid+1,r,L,R));
}
int main(){
int n=read(),q=read(),m=read();
scanf("%s",str+1);
reverse(str+1,str+1+m);
for(int i=1;i<=n;++i){
len[i]=read();
}
for(int i=1;i<=m;++i)ins(i);
Build(1,1,n);
int lst=0;
char opt[12];
for(int i=1;i<=q;++i){
scanf("%s",opt);
if(opt[0]=='I'){
int x=read();
str[++m]='a'+(x^lst);
ins(m);
}
if(opt[0]=='C'){
int x=read(),pos=read();
len[x]=pos;
update(1,1,n,x);
}
if(opt[0]=='Q'){
int l=read(),r=read();
printf("%d\n",lst=query(1,1,n,l,r));
}
}
}
Problem C: The Winds of Winter
Time Limit: 1000 ms Memory Limit: 512 MB
Description
Given an n-point tree, for each node in the tree, it will be deleted, and then any one of the forest can be obtained point his father disconnected and connected to the other tree, for each point obtain the minimum value of the maximum size of all trees in the forest.
Input
The first line, a number n.
Of 2 ~ n + 1 lines of two integers x, y, (1 <= x <= y <= n), y represents the father of x is (if x = 0 then y is the root).
Output
A total of n lines of a number, the answer to the i-th row represents the point i omitted.
Sample Input
10
0 1
1 2
1 3
1 4
2 5
2 6
3 7
4 8
4 9
5 10
Sample Output
3
4
5
5
5
9
9
9
9
9
HINT
10% of the data, n <= 10
30% of the data, n <= 10 ^ 3
100% data, n <= 10 ^ 5
Solution
Gugu Gu