zoukankan      html  css  js  c++  java
  • Edu10

    Edu10

    传送门

    C:一个n排列,其中有m对数,问有多少个区间满足区间里不含成对的数

    对于一对数对应的下标(l,r),若一个区间左端点为l,那么右端点必须<r,否则就含有(l,r)这一对了.遍历一遍后,发现会有[l,r-1]中包含其他pair的情况,就需要从后往前遍历,i位置到达的最远下标不能大于i+1位置到达的最远下标,不然就包含了i+1那一段.

    int n,m;
    int vis[N]; //i对应下标
    int dp[N];  //下标i能到的最远位置
    void work() {
    	scanf("%d%d",&n,&m);
    	for(int i=1; i<=n; i++) {
    		int v;
    		scanf("%d",&v);
    		vis[v]=i;
    		dp[i] = n+1;
    	}
    	while(m--) {
    		int l,r;
    		scanf("%d%d",&l,&r);
    		if(vis[l] > vis[r])swap(l,r);
    		dp[vis[l]] = min(dp[vis[l]],vis[r]);
    	}
    	for(int i=n-1; i>=1; i--) {
    		dp[i] = min(dp[i],dp[i+1]);
    	}
    	ll ans =0;
    	for(int i=1; i<=n; i++) {
    		ans += dp[i] - i;
    	}
    	printf("%lld
    ",ans);
    }
    

    D.树状数组+离散化

    题意:一堆线段,问你每条线段内"包含"了几条其他线段.

    将线段按照右端点升序排序,对于线段i和i-1,因为i.r >= (i-1).r,所以若(i-1).l >= i.l,那么i-1线段就在i里面.

    同理,对于线段x,只需看1~x-1中有多少左端点 >= x.l.

    把左端点用树状数组维护,sum(x.r)-sum(x.l-1)表示包含的左端点个数.(注意开两倍空间....WA了无数次)

    const int N = 4e5 + 50;
    
    int n;
    int l[N],r[N];
    int lsh[N],tot =0;
    int c[N];
    
    int lowbit(int n) {
    	return n & (-n);
    }
    void update(int x,int y) {
    	for(; x<=N; x+=lowbit(x))c[x] += y;
    }
    int sum(int x) {
    	int ans =0 ;
    	for(; x; x-=lowbit(x))ans += c[x];
    	return ans;
    }
    
    struct node {
    	int l,r;
    	int id;
    } p[N];
    
    bool cmp(node a,node b) {
    	if(a.r != b.r)return a.r < b.r;
    	return a.l > b.l;
    }
    int ans[N];
    
    void work() {
    	scanf("%d",&n);
    	for(int i=0; i<n; i++) {
    		scanf("%d%d",&p[i].l,&p[i].r);
    		if(p[i].l > p[i].r)swap(p[i].r,p[i].l);
    		p[i].id = i;
    		lsh[tot++] = p[i].l;
    		lsh[tot++] = p[i].r;
    	}
    	sort(lsh,lsh+tot);
    	tot = unique(lsh,lsh+tot)-lsh;
    	sort(p,p+n,cmp);
    
    	for(int i=0; i<n; i++) {
    		int lll = lower_bound(lsh,lsh+tot,p[i].l)-lsh +1;
    		int rrr = lower_bound(lsh,lsh+tot,p[i].r)-lsh+1;
    		if(lll > rrr)swap(lll,rrr);
    		int l1 = sum(lll-1);
    		int r1 = sum(rrr);
    		ans[p[i].id] = r1-l1;
    		update(lll,1);
    	}
    	for(int i=0; i<n; i++) {
    		printf("%d
    ",ans[i]);
    	}
    }
    
  • 相关阅读:
    ZooKeeper 授权访问
    jQuery代码优化:事件委托篇
    设计一个学生作业完成情况的管理程序
    UVa 10192 Vacation(LCS水题)
    BBS快照源代码代写
    ftp服务器系统编程编码程序下载代写代开发
    文件夹病毒专杀工具
    C#生成软件注册码
    《恐怖丛林生存》肉搏攻略,解开星星系统之谜
    《恐怖丛林生存》各种bug 各种解密
  • 原文地址:https://www.cnblogs.com/LaiYiC/p/14969447.html
Copyright © 2011-2022 走看看