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]);
}
}