noip2019 training test events (three)

Problem A: string

Time Limit: 5000 ms Memory Limit: 256 MB

Description

Given a string of length S and a length of n is m T string defined Ai = S1S2 ... SiT1T2 ... TmSi + 1Si + 2 ... SN

If i = 0 indicates T string S in front of the string, if the string S i = n denotes the string in front of the T.

For a query l, r, k, x, y, find the lexicographically smallest Ai, if the minimum output to a plurality of lexicographically smallest i, if there is output to meet the conditions i -1 wherein i satisfies l≤ i≤r and x≤ (i mod k) ≤y.

Input

The first line of the input character string and the string S T and an integer q, q denotes a query

For each interrogation total line number 5 l, r, k, x, y

Output

A total number of line q, q represents an answer

Sample Input
abc d 4
0 3 2 0 0
0 3 1 0 0
1 2 1 0 0
0 1 3 2 2
Sample Output
2 3 2 -1

HINT

For 30% of the data 1≤n, m, q≤10 ^ 3

To 100% data 1≤n, m, q≤10 ^ 5

Solution

Not write it down. . . LCP is probably the first row with a query sequence and then sub-blocks

Code to achieve more nausea, time to say it.

Problem B: mex

Time Limit: 1000 ms Memory Limit: 512 MB

Description

Give you an infinite array, the initial time are zero, there are three modes of operation:

1 is given to the operation interval [l, r] is set to 1,

2 is given to the operation interval [l, r] is set to 0,

Operation 3 given interval [l, r] 0,1 reversed.

A total of n operation, the operation to output 0 after each minimum position.

Input

A first line integer n, there are n represents operation

Next n lines, each line three integers op, l, r represents an operation

Output

A total of n rows, one row represents an integer answer

Sample Input
3
1 3 4
3 1 6
2 1 3
Sample Output
1
3
1

HINT

For 30% of the data 1≤n≤10 ^ 3,1≤l≤r≤10 ^ 18

To 100% data 1≤n≤10 ^ 5,1≤l≤r≤10 ^ 18

Solution

L and r see a data range, then survive discrete offline

Remember to coordinate discretized into three: the middle l, r, r + 1, such that the two portions can be represented interrogation

Consider maintaining minimum position l, r in the interval 0 occurs with the segment tree

Then build two tree line, a full initialization is 0, a full 1

When modifying directly the two together, all leveled; as when both sides of the inverted node to exchange enough.

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define INF 1000000000000000001
struct node{
    int l,r;
    int pos;
    int tag;
}t[2000001];
int cnt;
int root[2];
int siz;
void build(int &o,int l,int r,bool mark){
    if(!o)o=++cnt;
    t[o].tag=-1;
    if(l==r){
        if(mark)t[o].pos=l;
        else t[o].pos=siz+1;
        return;
    }
    int mid=(l+r)/2;
    build(t[o].l,l,mid,mark);
    build(t[o].r,mid+1,r,mark);
    t[o].pos=min(t[t[o].l].pos,t[t[o].r].pos);
}
void pushdown(int o,int l,int r){
    int ls=t[o].l,rs=t[o].r;
    if(t[o].tag==-1)return;
    t[ls].tag=t[rs].tag=t[o].tag;
    if(t[o].tag==0){
        t[ls].pos=t[rs].pos=siz+1;
    }
    else {
        t[ls].pos=l;
        t[rs].pos=(l+r)/2+1;
    }
    t[o].tag=-1;
}
void update(int o1,int o2,int l,int r,int L,int R){
    //cout<<o1<<" "<<o2<<endl;
    if(L<=l&&r<=R){
        t[o1].pos=siz+1;
        t[o2].pos=l;
        //cout<<l<<endl;
        t[o1].tag=0;
        t[o2].tag=1;
        return;
    }
    pushdown(o1,l,r);
    pushdown(o2,l,r);
    int mid=(l+r)/2;
    if(L<=mid)update(t[o1].l,t[o2].l,l,mid,L,R);
    if(R>mid)update(t[o1].r,t[o2].r,mid+1,r,L,R);
    t[o1].pos=min(t[t[o1].l].pos,t[t[o1].r].pos);
    t[o2].pos=min(t[t[o2].l].pos,t[t[o2].r].pos);
    //cout<<t[o1].pos<<" "<<t[o2].pos<<endl;
}
void swaps(int &o1,int &o2,int l,int r,int L,int R){
    //cout<<o1<<" "<<o2<<endl;
    if(L<=l&&r<=R){
        swap(o1,o2);
        return;
    }
    pushdown(o1,l,r);
    pushdown(o2,l,r);
    int mid=(l+r)/2;
    if(L<=mid)swaps(t[o1].l,t[o2].l,l,mid,L,R);
    if(R>mid)swaps(t[o1].r,t[o2].r,mid+1,r,L,R);
    t[o1].pos=min(t[t[o1].l].pos,t[t[o1].r].pos);
    t[o2].pos=min(t[t[o2].l].pos,t[t[o2].r].pos);
}
int query(int x){
    return t[root[x]].pos;
}
struct que{
    int opt;
    int l,r;
}p[400001],q[400001];
int lis[400001];
int tot;
int minx=-1;
int pos[400001];
signed main(){
    int n;
    scanf("%lld",&n);
    for(int i=1;i<=n;++i){
        scanf("%lld%lld%lld",&p[i].opt,&p[i].l,&p[i].r);
        lis[++tot]=p[i].l;
        lis[++tot]=p[i].r;
        lis[++tot]=p[i].r+1;
        if(minx==-1)minx=min(p[i].l,p[i].r);
        else minx=min(minx,min(p[i].l,p[i].r));
    }
    sort(lis+1,lis+1+tot);
    siz=unique(lis+1,lis+1+tot)-lis-1;
    //cout<<siz<<endl;
    for(int i=1;i<=siz;++i)pos[i]=lis[i];
    pos[siz+1]=INF;
    for(int i=1;i<=n;++i){
        q[i].opt=p[i].opt;
        q[i].l=(lower_bound(lis+1,lis+1+siz,p[i].l))-lis;
        q[i].r=(lower_bound(lis+1,lis+1+siz,p[i].r))-lis;
        //cout<<q[i].opt<<" "<<q[i].l<<" "<<q[i].r<<endl;
    }
    build(root[0],1,siz,true);
    build(root[1],1,siz,false);
    //cout<<cnt<<endl;
    for(int i=1;i<=n;++i){
        if(minx>1){
            puts("1");
            continue;
        }
        if(q[i].opt==1){
            update(root[0],root[1],1,siz,q[i].l,q[i].r);
        }
        if(q[i].opt==2){
            update(root[1],root[0],1,siz,q[i].l,q[i].r);
        }
        if(q[i].opt==3){
            swaps(root[0],root[1],1,siz,q[i].l,q[i].r);
        }
        printf("%lld\n",pos[query(0)]);
    }
}

Problem C: MST

Time Limit: 2000 ms Memory Limit: 256 MB

Description

Given a point n and m edges connected graph, and a weight to ensure that no self-loop edge. For each edge is obtained, in the case where the other side of the same weight, which can take the maximum priority value, all this such that the upper edge in the minimum spanning tree of a connected graph. If the maximum weight is infinite, the output 1.

Input

The first line of two integers n, m, m denotes n points edges

Next m lines of three integers x, y, z, z represents one of the long sides there between node x and node y

Output

m integers output line, each edge represents answers

Sample Input
4 4
1 2 2
2 3 2
3 4 2
4 1 3
Sample Output
2 2 2 1 

HINT

For 30% of the data 1≤n≤10 ^ 3,1≤m≤3 * 10 ^ 3

To 100% data 1≤n, m≤2 * 10 ^ 5,1≤z≤10 ^ 9

Solution

We first minimum spanning tree built out.

Then, for an outer edge of the minimum spanning tree (x, y), find the largest one side in the path of the minimum spanning tree x ~ y. In order to make it always on the minimum spanning tree, this edge of the right side into the largest value of -1 on it

Similarly, for (x, y, lca) the loop, the value of the edge in the minimum spanning tree should be at least (x, y) of weight -1. Then on the edge in the minimum spanning tree continuously takes a minimum value at the (x, y), then the answer is the minimum value -1.

These two things are obvious.

Then we multiply what you can do.

#include<bits/stdc++.h>
using namespace std;
struct qwq{
    int u,v;
    int w;
    int nxt;
    int id;
}edge[1000001],edge1[1000001];
int fa[1000001];
int findfa(int x){
    return x==fa[x]?x:fa[x]=findfa(fa[x]);
}
bool operator <(qwq a,qwq b){
    return a.w<b.w;
}
int n,m;
bool vis[1000001];
void kruskal(){
    sort(edge1+1,edge1+1+m);
    for(int i=1;i<=n;++i)fa[i]=i;
    int tmp=0;
    for(int i=1;i<=m;++i){
        int u=edge1[i].u,v=edge1[i].v;
        int x=findfa(u),y=findfa(v);
        if(x!=y){
            vis[i]=true;
            fa[y]=x;
            tmp++;
        }
        if(tmp==n-1)break;
    }
}
int cnt=-1;
int head[1000001];
void add(int u,int v,int w,int id){
    edge[++cnt].nxt=head[u];
    edge[cnt].u=u;
    edge[cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].id=id;
    head[u]=cnt;
}
int re[1000001];
void addedge(){
    for(int i=1;i<=m;++i){
        int u=edge1[i].u,v=edge1[i].v,w=edge1[i].w,id=edge1[i].id;
        if(vis[i]){
            add(u,v,w,id);
            add(v,u,w,id);
        }
    }
}
int f[1000001][21];
int maxn[1000001][21];
int dep[1000001];
void dfs(int u,int fa){
    for(int i=1;i<=20;++i){
        f[u][i]=f[f[u][i-1]][i-1];
        maxn[u][i]=max(maxn[u][i-1],maxn[f[u][i-1]][i-1]);
    }
    for(int i=head[u];~i;i=edge[i].nxt){
        int v=edge[i].v,w=edge[i].w,id=edge[i].id;
        if(v!=f[u][0]){
            re[v]=id;
            maxn[v][0]=w;
            f[v][0]=u;
            dep[v]=dep[u]+1;
            dfs(v,u);
        }
    }
}
int LCA(int x,int y,int &lca){
    int ans=0;
    if(dep[x]<dep[y])swap(x,y);
    int depth=dep[x]-dep[y];
    for(int i=0;i<=20;++i){
        if(depth&(1<<i)){
            ans=max(ans,maxn[x][i]);
            x=f[x][i];
        }
    }
    if(x==y){
        lca=x;
        return ans;
    }
    for(int i=20;i>=0;--i){
        if(f[x][i]==f[y][i])continue;
        ans=max(ans,max(maxn[x][i],maxn[y][i]));
        x=f[x][i],y=f[y][i];
    }
    lca=f[x][0];
    ans=max(ans,max(maxn[x][0],maxn[y][0]));
    return ans;
}
int ans[1000001];
void solve(int x,int u,int w){
    x=findfa(x);
    while(dep[x]>dep[u]){
        ans[re[x]]=max(ans[re[x]],w);
        //cout<<re[x]<<endl;
        int y=findfa(f[x][0]);
        fa[x]=y;
        x=findfa(x);
    }
}
int main(){
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i){
        scanf("%d%d%d",&edge1[i].u,&edge1[i].v,&edge1[i].w);
        edge1[i].id=i;
        ans[i]=-1;
    }
    kruskal();
    addedge();
    dfs(1,-1);
    for(int i=1;i<=n;++i)fa[i]=i;
    for(int i=1;i<=m;++i){
        int u=edge1[i].u,v=edge1[i].v,w=edge1[i].w;
        int id=edge1[i].id;
        if(!vis[i]){
            int lca;
            ans[id]=LCA(u,v,lca)-1;
            //cout<<i<<endl;
            //cout<<u<<" "<<v<<" "<<lca<<endl;
            //cout<<ans[id]<<endl;
            solve(u,lca,w-1);
            solve(v,lca,w-1);
        }
    }
    for(int i=1;i<=m;++i){
        printf("%d ",ans[i]);
    }
}

Guess you like

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