• 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]);
    	}
    }
    
  • 相关阅读:
    Validation failed for one or more entities
    sql 存储过程
    SQL Server分页3种方案比拼
    case when 用法
    C#如何计算代码执行时间
    透过 Jet.OLEDB 读取 Excel里面的数据
    DataBinding?资料系结?资料绑定?
    ASP.NET的OutputCache
    我想写程序#3 之 「简单地设计自己的数据表(Table)」
    我想写程序#1 之 「先确立志向」
  • 原文地址:https://www.cnblogs.com/LaiYiC/p/14969447.html
Copyright © 2020-2023  润新知