zoukankan      html  css  js  c++  java
  • test20180922 世界第一的猛汉王

    题意

    分析


    由于异色点必有连边,所以一个点的covered减去两个点共有的covered就是可存在的环数,十分巧妙。

    #include <bits/stdc++.h>
    
    using LL = long long;
    
    const int MAXN = 1e5 + 5;
    
    int n, m, D;
    
    std::pair<LL, LL> p1[MAXN], p2[MAXN];
    
    struct Event {
        LL x, y; int val;
        
        Event() = default;
        Event(LL _x, LL _y, int _v): x(_x), y(_y), val(_v) {}
    }; std::vector<Event> events; // 扫描线事件 
    std::vector<LL> xlist, sorted; // x离散化列表,y离散化列表 
    
    namespace BIT {
        int sum[MAXN * 3];
        
        void Init() {
            memset(sum, 0, sizeof sum);
        }
        
    #define lowbit(x) ((x) & -(x))
        
        void Add(int a, int x) {
            for (int i = a; i <= (int)sorted.size(); i += lowbit(i))
                sum[i] += x;
        }
        
        int Query(int a) {
            int res = 0;
            for (int i = a; i > 0; i -= lowbit(i))
                res += sum[i];
            return res;
        }
    }
    
    LL minAns = 0, maxAns = 0, minus = 0; // 加、减的总和 
    
    int covered[MAXN];
    
    int Y(LL y) {
        return std::lower_bound(sorted.begin(), sorted.end(), y) - sorted.begin() + 1;
    }
    
    LL C2(LL x) {
        return x * (x - 1) / 2;
    }
    
    void Solve() {
        events.clear(); // p2中x起止&y&+-1 
        xlist.clear(); // p2中x起止, p1中x 
        sorted.clear(); // p2中y,p1中y起止 
        
        for (int i = 1; i <= m; ++i) {
            events.emplace_back(p2[i].first - D, p2[i].second, 1);
            events.emplace_back(p2[i].first + D + 1, p2[i].second, -1);
            
            xlist.push_back(p2[i].first - D);
            xlist.push_back(p2[i].first + D + 1);
            
            sorted.push_back(p2[i].second);
        }
        for (int i = 1; i <= n; ++i) {
            xlist.push_back(p1[i].first);
            
            sorted.push_back(p1[i].second - D - 1);
            sorted.push_back(p1[i].second + D);
        }
        
        std::sort(xlist.begin(), xlist.end());
        xlist.erase(std::unique(xlist.begin(), xlist.end()), xlist.end());
        
        std::sort(sorted.begin(), sorted.end());
        sorted.erase(std::unique(sorted.begin(), sorted.end()), sorted.end());
        
        std::sort(events.begin(), events.end(), [] (const Event &a, const Event &b) { return a.x < b.x; });
        
        BIT::Init();
         
        int j1 = 0, j2 = 1;
        
        for (LL x: xlist) {
            while (j1 < (int)events.size() && events[j1].x == x) { // 把离散化的纵坐标加进去 
                BIT::Add(Y(events[j1].y), events[j1].val);
                ++j1;
            }
            
            while (j2 <= n && p1[j2].first == x) {
                covered[j2] = BIT::Query(Y(p1[j2].second + D)) - BIT::Query(Y(p1[j2].second - D - 1)); // 询问离散化的纵坐标的区间和 
                ++j2;
            }
        }
        
        std::sort(covered + 1, covered + n + 1);
        
        for (int i = 1; i <= n; ++i) {
            minAns += 1LL * (n - i) * covered[i]; // n-i个比它大 
            maxAns += 1LL * (n - i) * covered[n - i + 1]; // n-i个比它小 
            minus += C2(covered[i]); // 加到减的总和里面 
        }
    }
    
    int main() {
    #ifndef LOCAL
        freopen("mhw.in", "r", stdin);
        freopen("mhw.out", "w", stdout);
    #endif
        
        scanf("%d%d%d", &n, &m, &D);
        for (int i = 1; i <= n; ++i) {
            static int x, y;
            
            scanf("%d%d", &x, &y);
            p1[i] = std::make_pair(x + y, x - y);
        }
        for (int i = 1; i <= m; ++i) {
            static int x, y;
            
            scanf("%d%d", &x, &y);
            p2[i] = std::make_pair(x + y, x - y);
        }
        std::sort(p1 + 1, p1 + n + 1);
        std::sort(p2 + 1, p2 + m + 1);
        
        Solve();
        
        std::swap(n, m);
        std::swap(p1, p2);
        
        Solve();
        
        printf("%lld %lld
    ", minAns - minus, maxAns - minus);
        
        return 0;
    }
    

    mine

    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<ctime>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<list>
    #include<deque>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<complex>
    #pragma GCC optimize ("O0")
    using namespace std;
    template<class T> inline T read(T&x)
    {
        T data=0;
    	int w=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
        while(isdigit(ch))
            data=10*data+ch-'0',ch=getchar();
        return x=data*w;
    }
    typedef long long ll;
    const int INF=0x7fffffff;
    
    const int MAXN=1e5+7;
    int n,m,D;
    
    pair<ll,ll> p1[MAXN],p2[MAXN];
    
    struct Event
    {
    	ll x,y;
    	int val;
    	
    	Event()=default;
    	Event(ll x,ll y,int v): x(x),y(y),val(v) {}
    };
    vector<Event> events;
    vector<ll> xlist,sorted;
    
    struct BIT
    {
    	int sum[MAXN*3];
    	
    	void init()
    	{
    		memset(sum,0,sizeof(sum));
    	}
    #define lowbit(x) ((x)&(-x))
    	void add(int p,int v)
    	{
    		for(int i=p;i<=(int)sorted.size();i+=lowbit(i))
    			sum[i]+=v;
    	}
    	
    	int query(int p)
    	{
    		int res=0;
    		for(int i=p;i>0;i-=lowbit(i))
    			res+=sum[i];
    		return res;
    	}
    }T;
    
    ll minans,maxans,minussum;
    int covered[MAXN];
    
    int Y(ll y)
    {
    	return lower_bound(sorted.begin(),sorted.end(),y)-sorted.begin()+1;
    }
    
    ll C2(ll x)
    {
    	return x*(x-1)/2;
    }
    
    void solve()
    {
    	events.clear();
    	xlist.clear();
    	sorted.clear();
    	
    	for(int i=1;i<=m;++i)
    	{
    		events.emplace_back(p2[i].first-D,p2[i].second,1);
    		events.emplace_back(p2[i].first+D+1,p2[i].second,-1);
    		
    		xlist.push_back(p2[i].first-D);
    		xlist.push_back(p2[i].first+D+1);
    		
    		sorted.push_back(p2[i].second);
    	}
    	
    	for(int i=1;i<=n;++i)
    	{
    		xlist.push_back(p1[i].first);
    		
    		sorted.push_back(p1[i].second-D-1); // 查询的时候用 
    		sorted.push_back(p1[i].second+D);
    	}
    	
    	sort(xlist.begin(),xlist.end());
    	xlist.erase(unique(xlist.begin(),xlist.end()),xlist.end());
    	
    	sort(sorted.begin(),sorted.end());
    	sorted.erase(unique(sorted.begin(),sorted.end()),sorted.end());
    	
    	sort(events.begin(),events.end(),[] (const Event &a,const Event &b) { return a.x<b.x; });
    	
    	T.init();
    	
    	int i=0,j=1;
    	
    	for(ll x:xlist)
    	{
    		while(i<(int)events.size()&&events[i].x==x)
    		{
    			T.add(Y(events[i].y),events[i].val);
    			++i;
    		}
    		while(j<=n&&p1[j].first==x)
    		{
    			covered[j]=T.query(Y(p1[j].second+D))-T.query(Y(p1[j].second-D-1));
    			++j;
    		}
    	}
    	
    	sort(covered+1,covered+n+1);
    	
    	for(int i=1;i<=n;++i)
    	{
    		minans+=(ll)(n-i)*covered[i];
    		maxans+=(ll)(i-1)*covered[i];
    		minussum+=C2(covered[i]);
    	}
    }
    
    int main()
    {
      freopen("mhw.in","r",stdin);
      freopen("mhw.out","w",stdout);
    	read(n);read(m);read(D);
    	for(int i=1;i<=n;++i)
    	{
    		static int x,y;
    		read(x);read(y);
    		p1[i]=make_pair(x+y,x-y);
    	}
    	for(int i=1;i<=m;++i)
    	{
    		static int x,y;
    		read(x);read(y);
    		p2[i]=make_pair(x+y,x-y);
    	}
    	sort(p1+1,p1+n+1);
    	sort(p2+1,p2+m+1);
    	
    	solve();
    	
    	swap(n,m);
    	swap(p1,p2);
    	solve();
    	
    	printf("%lld %lld
    ",minans-minussum,maxans-minussum);
    //  fclose(stdin);
    //  fclose(stdout);
        return 0;
    }
    
  • 相关阅读:
    [转]oracle 10g数据泵之impdp-同时导入多个文件
    IMP数据到指定的表空间
    [转]Oracle数据泵的使用
    [转]oracle pump expdp impdp使用
    liunx 安装ActiveMQ 及 spring boot 初步整合 activemq
    安装本地jar包到仓库
    centos7.4 64位安装 git
    出现 CannotAcquireLockException 异常
    centos7.4 64位安装 redis-4.0.0
    java代码定时备份mysql数据库及注意事项——基于 springboot
  • 原文地址:https://www.cnblogs.com/autoint/p/9710515.html
Copyright © 2011-2022 走看看