差分简单题集

 

【一维差分】Codeforces 1000C Covered Points Count 

题目大意:

给定$n$个线段,给定这些线段所在的区间($l,r\leq10^{18}$),这些线段能够覆盖它们所包含的点,问你被包含$[1,n]$次的点分别有多少个。

解题分析:
用差分来高效的统计一下指定区间内所被覆盖的线段个数,同时,因为$l,r$的大小非常大,所以我们需要对所有的线段进行离散化。

#include <bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T&x){        
    x=0;int f=1;char ch=getchar();
    while(ch<'0' ||ch>'9'){ if(ch=='-')f=-1; ch=getchar(); }
    while(ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
    x*=f;
}
#define REP(i,s,t) for(int i=s;i<=t;i++)
typedef long long ll;
map<ll,ll>mp;
int main(){
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int n;cin>>n;
    REP(i,1,n){
        ll l,r;read(l);read(r);
        mp[l]++,mp[r+1]--;
    }
    vector<ll>ans(n+10);
    ll last=0,sum=0;    //last统计上一个区间端点的下标,sum计算前缀和
    for(auto e:mp){
        ans[sum]+=(e.first-last);      
        sum+=e.second;
        last=e.first;
    }
    REP(i,1,n)cout<<ans[i]<<" ";
}
View Code

 

 

 

 

【一维差分】Codeforces 853B Jury Meeting (差分+前缀和)

 

 

 

 

【二维差分】HDU 6514 Monitor(差分+前缀和) 经典

题目大意:

给定一个大小为n*m的矩形,然后给定q1个监视器,每个监视器的监视范围为(x1,y1)~(x2,y2)(分别为左上角和右下角的坐标)。然后进行q2次询问,每次询问给定一个小的子矩阵,问你这个子矩阵是否被上面的监视器完全覆盖。

解题分析:

因为本题数据范围给的是:$n*m<=10^7$,所以需要想到二维转一维。

#include <bits/stdc++.h>
using namespace std;

#define rep(i,s,t) for(int i=s;i<=t;i++)
const int N = 1e7+5;
int n,m,a[N];
inline int id(int i,int j){ return (i-1)*m+j; }
inline void add(int i,int j,int val){ a[id(i,j)]+=val; }
inline int query(int i,int j){
    if(i==0||j==0)return 0;      
    return a[id(i,j)];
}
int main(){
    while(~scanf("%d%d",&n,&m)){
        int q1,q2,x1,x2,y1,y2;;
        cin>>q1;
        //memset(a,0,sizeof(a));       //这里看需不需要换成循环
        rep(i,0,n*m)a[i]=0;
        rep(i,1,q1){
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            add(x1,y1,1);add(x1,y2+1,-1);add(x2+1,y1,-1);add(x2+1,y2+1,1);
        }
        rep(i,1,n) rep(j,1,m) {
            a[id(i,j)]=query(i-1,j)+query(i,j-1)-query(i-1,j-1)+a[id(i,j)];
        }
        rep(i,1,n) rep(j,1,m) if(a[id(i,j)]!=0) {
            a[id(i,j)]=1;
        }
        rep(i,1,n) rep(j,1,m) {
            a[id(i,j)]=query(i-1,j)+query(i,j-1)-query(i-1,j-1)+a[id(i,j)];
        }
        cin>>q2;while(q2--){
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            int ans=query(x2,y2)-query(x2,y1-1)-query(x1-1,y2)+query(x1-1,y1-1);
            if(ans==(x2-x1+1)*(y2-y1+1))puts("YES");
            else puts("NO");
        }
    }    
}
View Code

 

 

 

 

【二维差分】POJ 2155 Matrix (二维树状数组+差分)

 

 

 

 

【树上差分】CodeForces 739B Alyona and a tree (二分+树上差分)

 

转载于:https://www.cnblogs.com/00isok/p/10927070.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值