zoukankan      html  css  js  c++  java
  • bzoj3295: [Cqoi2011]动态逆序对

    题目链接

    bzoj3295: [Cqoi2011]动态逆序对

    题解

    好神呐,删除转化为插入,然后得到了插入的时间关系
    然后问题就转化成了三维偏序问题

    代码

    #include <iostream>
    #include <cstdio>
    // n * (2 * n + 1) + 1; 
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const int N=2e5+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m;
    int pos[N];
    struct Q{
        int t,x,y; 
        Q(int t,int id,int v):t(t),x(id),y(v){}
        bool operator < (const Q & A)const{
            return x == A.x ? y < A.y : x < A.x; 
        } 
    }q[N],t[N]; 
    inline bool cmp(const Q &q,const Q &b) {   
      	return q.t == b.t ? q.x<b.x : q.t<b.t;
    }
    int c[N];  
    namespace BIT {
    #define lowbit(x) (x & -x)	
    	int sum[maxn]; 
    	void add(int idx,int val) {
    		for(;idx <= n;idx += lowbit(idx)) sum[idx] += val; 	 
    	} 
    	int query(int idx) { 
    		int ret = 0;for(;idx;idx -= lowbit(idx)) ret += sum[idx]; 
    		return ret;  
    	} 
     	
    }  
    LL ans[N];  
    void cdq(int l,int r) {  
        if(l == r) return; 
        int mid = (l + r) >> 1; 
        cdq(l,mid); cdq(mid + 1,r); 
        int i = l,j = mid + 1,p = l; 
        while(i <= mid && j <= r) {  
            if(q[i] < q[j]) BIT::add(q[i].y,1),t[p ++] = q[i ++];  
            else ans[q[j].t] += BIT::query(n) - (q[j].y) , t[p++] = q[j ++]; 
        } 
        for(int i = l;i <= mid;i ++) add(q[i].y,- 1); 
        for(int i = l;i <= r;i ++) q[i] = t[i]; 
        for(int i = r;i >= l;i --) { 
            if(q[i].t <= mid) add(q[i].y,1); 
            else ans[q[i].t] += sum(q[i].y); 
        } 
        for(int i=l;i<=r;i++) if(q[i].t<=mid) add(q[i].y,-1);
    }
    int main() { 
        n = read(); m = read();
        for(int i = 1;i <= n ;i ++) q[i] = Q(0,i,read()) , pos[q[i].y] = i;
        int Tim = n; 
        for(int i = 1;i <= m;i ++) q[pos[read()]].t = Tim --;  
        for(int i = 1;i <= n;i ++) if(!q[i].t) q[i].t = Tim --;  
    	sort(q + 1,q + 1 + n,cmp); 
        cdq(1,n);  
        for(int i=1;i<=n;i++) ans[i]+=ans[i-1]; 
        for(int i=n;i>=n-m+1;i--) printf("%lld
    ",ans[i]);
    } 
    
  • 相关阅读:
    ASP.NET编程的十大技巧
    C#学习心得(转)
    POJ 1177 Picture (线段树)
    POJ 3067 Japan (树状数组)
    POJ 2828 Buy Tickets (线段树)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4235 Flowers (线段树)
    POJ 2886 Who Gets the Most Candies? (线段树)
    POJ 2418 Cows (树状数组)
    HDU 4339 Query (线段树)
  • 原文地址:https://www.cnblogs.com/sssy/p/9260532.html
Copyright © 2011-2022 走看看