QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#132785#5425. Proposition CompositionkkioTL 1ms21964kbC++146.0kb2023-07-31 16:16:212023-07-31 16:16:26

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-07-31 16:16:26]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:21964kb
  • [2023-07-31 16:16:21]
  • 提交

answer

#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
const int maxn=8e5+10;
struct SegT{
    int num0[maxn<<2],num1[maxn<<2],tag[maxn<<2];
    inline void pushtg(int i,int v)
    {
    	tag[i]+=v;
        if(v==0)return;
        if(v==1)num1[i]=num0[i],num0[i]=0;
        else num1[i]=num0[i]=0;
    }
    inline void pushdown(int i)
    {
        if(!tag[i])return;
        pushtg(i<<1,tag[i]);
        pushtg(i<<1|1,tag[i]);
        tag[i]=0;
    }
    inline void update(int i,int l,int r,int L,int R)
    {
    	if(L>R)return;
        if(L<=l&&r<=R)return pushtg(i,1),void();
        int mid=l+r>>1;pushdown(i);
        if(L<=mid)update(i<<1,l,mid,L,R);
        if(R>mid)update(i<<1|1,mid+1,r,L,R);
        num0[i]=num0[i<<1]+num0[i<<1|1];
        num1[i]=num1[i<<1]+num1[i<<1|1];
        //printf("%d %d %d %d\n",l,r,num0[i],num1[i]);
    }
    inline void build(int i,int l,int r)
    {
        tag[i]=0;
        if(l==r){num0[i]=1;num1[i]=0;return;}
        int mid=l+r>>1;
        build(i<<1,l,mid);
        build(i<<1|1,mid+1,r);
        num0[i]=num0[i<<1]+num0[i<<1|1];
        num1[i]=num1[i<<1]+num1[i<<1|1];
    }
}T1;
int id[maxn];
int pre[maxn],nxt[maxn],Lp[maxn],siz[maxn];
struct SegTV{
    int mn[maxn<<2],mx[maxn<<2];
    inline void modifypre(int i,int l,int r,int p,int v)
    {
        if(l==r){pre[l]=mn[i]=v;return;}
        int mid=l+r>>1;
        if(p<=mid)modifypre(i<<1,l,mid,p,v);
        else modifypre(i<<1|1,mid+1,r,p,v);
        mn[i]=min(mn[i<<1],mn[i<<1|1]);
    }
    inline void modifynxt(int i,int l,int r,int p,int v)
    {
        if(l==r){nxt[l]=mx[i]=v;return;}
        int mid=l+r>>1;
        if(p<=mid)modifynxt(i<<1,l,mid,p,v);
        else modifynxt(i<<1|1,mid+1,r,p,v);
        mx[i]=max(mx[i<<1],mx[i<<1|1]);
    }
    inline void findL(int i,int l,int r,int L,int R,int v,vector< pair<int,int> > &vec)
    {
    	if(L>R)return;
        if(mn[i]>=v)return;
        if(l==r){vec.push_back({id[l],l});return;}
        int mid=l+r>>1;
        if(L<=mid)findL(i<<1,l,mid,L,R,v,vec);
        if(R>mid)findL(i<<1|1,mid+1,r,L,R,v,vec);
    }
    inline void findR(int i,int l,int r,int L,int R,int v,vector< pair<int,int> > &vec)
    {
    	if(L>R)return;
        if(mx[i]<=v)return;
        if(l==r){vec.push_back({id[nxt[l]],nxt[l]});return;}
        int mid=l+r>>1;
        if(L<=mid)findR(i<<1,l,mid,L,R,v,vec);
        if(R>mid)findR(i<<1|1,mid+1,r,L,R,v,vec);
    }
    inline void build(int i,int l,int r,int *pre,int *nxt)
    {
        if(l==r){mn[i]=pre[l];mx[i]=nxt[l];return;}
        int mid=l+r>>1;
        build(i<<1,l,mid,pre,nxt);
        build(i<<1|1,mid+1,r,pre,nxt);
        mx[i]=max(mx[i<<1],mx[i<<1|1]);
        mn[i]=min(mn[i<<1],mn[i<<1|1]);
    }
}T2;
inline int calc(int x){return x*(x-1)/2;}
int ans;

int n,m,lid;
inline void getlist(vector<int> &A)
{
    ++lid;
    Lp[lid]=A[0];
    siz[lid]=A.size();
   // printf("newlist %d\n",lid);
    for(int v:A)id[v]=lid;
}
inline void cut(int i){int t=pre[i];T2.modifypre(1,1,n-1,i,i);T2.modifynxt(1,1,n-1,t,t);}
inline void link(int i,int j){T2.modifynxt(1,1,n-1,i,j);T2.modifypre(1,1,n-1,j,i);}
inline void cut(int lst,int L,int R)
{
    ans-=calc(siz[lst]);
    vector<int> l1,l2;
    int ptr1=Lp[lst],ptr2=L;
    while(1)
    {
        l1.push_back(ptr1),l2.push_back(ptr2);
        int n1=nxt[ptr1]==L?R:nxt[ptr1],n2=nxt[ptr2]==R?ptr2:nxt[ptr2];
        if(n1==ptr1)
        {
            getlist(l1);
            Lp[lst]=L;
            siz[lst]-=l1.size();
            ans+=calc(l1.size());
            ans+=calc(siz[lst]);
            break;
        }
        else if(n2==ptr2)
        {
            getlist(l2);
            siz[lst]-=l2.size();
            ans+=calc(l2.size());
            ans+=calc(siz[lst]);
            break;
        }
        ptr1=n1,ptr2=n2;
    }
    int t=pre[L];
    cut(L);cut(R);link(t,R);
}
inline int qry(int t)
{
    return ans+T1.num0[1]*(n-1+t-T1.num0[1])+T1.num1[1];
}
inline void cut2(int lst,int L)
{
    ans-=calc(siz[lst]);
    vector<int> l1,l2;
    int ptr1=Lp[lst],ptr2=L;
    //printf("?%d %d\n",lst,L);
    while(1)
    {
        l1.push_back(ptr1),l2.push_back(ptr2);
        int n1=nxt[ptr1]==L?ptr1:nxt[ptr1],n2=nxt[ptr2];
    //    printf("->%d %d\n",ptr1,ptr2);
        if(n1==ptr1)
        {
            getlist(l1);
            Lp[lst]=L;
            siz[lst]-=l1.size();
            ans+=calc(l1.size());
            ans+=calc(siz[lst]);
            break;
        }
        else if(n2==ptr2) 
        {
            getlist(l2);
            siz[lst]-=l2.size();
            ans+=calc(l2.size());
            ans+=calc(siz[lst]);
            break;
        }
        ptr1=n1,ptr2=n2;
    }
    cut(L);
}
void solve()
{
    cin>>n>>m;
    if(n==1)
    {
    	for(int i=1;i<=m;i++)
    	{
    		int l,r;cin>>l>>r;
    		puts("0");
		}
		return;
	}
    lid=1;
    ans=calc(n-1);
    Lp[1]=1;siz[1]=n-1;
    for(int i=1;i<=n-1;i++)pre[i]=i-1,nxt[i]=i+1;
    pre[1]=1;nxt[n-1]=n-1;
    for(int i=1;i<=n-1;i++)id[i]=1;
    T1.build(1,1,n-1);
    T2.build(1,1,n-1,pre,nxt);
    for(int i=1;i<=m;i++)
    {
        int l,r;
        cin>>l>>r;
        if(l!=r)
        {
	        if(l>r)swap(l,r);r--;
	        T1.update(1,1,n-1,l,r);
	        vector< pair<int,int> > vec;
	        T2.findL(1,1,n-1,l,r,l,vec);
	        T2.findR(1,1,n-1,l,r,r,vec);
	        sort(vec.begin(),vec.end());
	        vec.resize(unique(vec.begin(),vec.end())-vec.begin());
	        for(int i=0;i<vec.size();i++)
	        {
	            if(i<vec.size()-1&&vec[i].first==vec[i+1].first)
	                cut(vec[i].first,vec[i].second,vec[i+1].second),i++;
	            else 
	                cut2(vec[i].first,vec[i].second);
	        }
	    }
        cout<<qry(i)<<endl;
    }
    return;
}
signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    int T;cin>>T;
    while(T--)solve();
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 21964kb

input:

3
4 3
2 4
4 2
3 3
7 3
3 4
1 2
1 7
6 4
1 3
4 6
2 5
3 4

output:

6
5
6
21
24
10
15
12
3
2

result:

ok 10 numbers

Test #2:

score: -100
Time Limit Exceeded

input:

45540
10 9
10 1
1 10
10 1
1 10
1 10
10 1
1 10
3 3
10 1
10 4
1 2
1 10
3 4
1 10
7 6
7 1
5 6
1 7
6 6
7 1
6 7
9 7
3 3
7 7
5 4
1 1
9 1
9 1
6 5
8 7
1 8
4 4
5 6
1 1
1 8
6 6
4 5
3 3
3 2
3 1
3 3
3 9
3 1
3 3
2 2
3 3
3 1
2 2
1 1
2 3
3 1
10 1
2 1
7 1
1 7
3 8
1 3
1 3
3 3
1 3
2 2
1 3
1 3
3 3
3 6
3 1
1 3
1 3
1 3
1...

output:

45
36
36
36
36
36
36
36
36
45
36
28
21
21
15
10
10
10
6
36
44
50
57
28
21
15
28
28
21
21
15
15
10
3
1
1
3
3
3
3
1
1
1
0
0
45
21
3
1
1
1
1
1
1
1
3
1
1
1
1
1
45
36
36
36
36
36
36
36
3
3
1
0
0
0
0
0
0
3
1
0
0
15
10
10
28
34
21
6
6
6
6
1
0
0
21
15
15
45
53
10
13
6
3
3
3
3
21
15
15
15
10
10
21
15
3
1
1
0...

result: