[Fill file] noip2019 training test events (13)

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:

  1. In front of a character string is added

  2. Modifying a value of the element P

  3. 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.

  1. 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.

  2. C x pos the P [x] is modified pos.

  3. 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

Guess you like

Origin www.cnblogs.com/youddjxd/p/11425774.html