P3740 [HAOI2014]贴海报(离散化+线段树)

题目描述

Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论。为了统一管理,城市委员会为选民准备了一个张贴海报的electoral墙。

张贴规则如下:

  1. electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子;

  2. 所有张贴的海报的高度必须与electoral墙的高度一致的;

  3. 每张海报以“A B”表示,即从第A个格子到第B个格子张贴海报;

  4. 后贴的海报可以覆盖前面已贴的海报或部分海报。

现在请你判断,张贴完所有海报后,在electoral墙上还可以看见多少张海报。

输入输出格式

输入格式:

 

第一行: N M 分别表示electoral墙的长度和海报个数

接下来M行: Ai Bi 表示每张海报张贴的位置

 

输出格式:

 

输出贴完所有海报后,在electoral墙上还可以看见的海报数。

 

输入输出样例

输入样例#1:  复制
100 5
1 4
2 6
8 10
3 4
7 10
输出样例#1:  复制
4

说明

P3740 [HAOI2014]贴海报(离散化+线段树)_第1张图片

【约束条件】

1 0<= N <= 10000000 1<=M<=1000 1<= Ai <= Bi <=10000000

所有的数据都是整数。数据之间有一个空格



 

枚举每一海报,在枚举他后面的海报,先区间加1,后面的海报区间减到0位置;

离散的时候有端点左边加一个,左端点右边加一个



 

 

 

  1 #include"bits/stdc++.h"
  2 using namespace std;
  3 typedef long long ll;
  4 
  5 vector<int > v;
  6 
  7 int n,m;
  8 int tr[100000];
  9 int lazy[100000];
 10 struct aa
 11 {
 12     int l,r;
 13 }a[30000];
 14 
 15 void change(int rt,int l,int r,int L,int R,int v)
 16 { //  cout< 17 //    cout<<"tr,rt"<<" "<
 18     if (L<=l&&r<=R)
 19     {
 20         if (v==1)
 21         {
 22            tr[rt]+=r-l+1;
 23            lazy[rt]+=1;
 24         }
 25         else 
 26         {
 27             tr[rt]=max(0,tr[rt]-(r-l+1));
 28             lazy[rt]-=1;
 29         }
 30     //    cout<<"tr,rt"<<" "<
 31         return ;
 32     }
 33     
 34     if (lazy[rt]!=0)
 35     {
 36        int mid=l+r>>1;
 37        tr[rt<<1]+=lazy[rt]*(mid-l+1);
 38        tr[rt<<1]=max(tr[rt<<1],0);
 39        tr[rt<<1|1]+=lazy[rt]*(r-mid-1+1);
 40        tr[rt<<1|1]=max(tr[rt<<1|1],0);
 41        lazy[rt<<1]+=lazy[rt];
 42        lazy[rt<<1|1]+=lazy[rt];
 43        lazy[rt]=0;
 44            
 45     }
 46     
 47     int mid = l+r>>1;
 48     if (L<=mid)change(rt<<1,l,mid,L,R,v);
 49      if (R>mid)change(rt<<1|1,mid+1,r,L,R,v);
 50     tr[rt]=tr[rt<<1]+tr[rt<<1|1];
 51 }
 52 
 53 
 54 int query(int rt,int l,int r,int L,int R)
 55 {
 56     if (L<=l&&r<=R)return tr[rt]; int mid=l+r>>1;
 57     
 58         if (lazy[rt]!=0)
 59     {
 60        int mid=l+r>>1;
 61        tr[rt<<1]+=lazy[rt]*(mid-l+1);
 62        tr[rt<<1]=max(tr[rt<<1],0);
 63        tr[rt<<1|1]+=lazy[rt]*(r-mid-1+1);
 64        tr[rt<<1|1]=max(tr[rt<<1|1],0);
 65        lazy[rt<<1]+=lazy[rt];
 66        lazy[rt<<1|1]+=lazy[rt];
 67        lazy[rt]=0;
 68            
 69     }
 70     int t=0; if (L<=mid)t+=query(rt<<1,l,mid,L,R);
 71     if (R>mid)t+=query(rt<<1|1,mid+1,r,L,R); return t; 
 72 }
 73 int main()
 74 {
 75     cin>>n>>m;
 76     for (int i=1;i<=m;i++)
 77     {
 78         scanf("%d%d",&a[i].l,&a[i].r);
 79         v.push_back(a[i].r); v.push_back(a[i].l); 
 80         if (a[i].r-a[i].l>1)v.push_back(a[i].l+1),v.push_back(a[i].r-1); 
 81     } int tot;
 82     sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end());
 83     for (int i=1;i<=m;i++)
 84     a[i].l=lower_bound(v.begin(),v.end(),a[i].l)-v.begin()+1,
 85     a[i].r=lower_bound(v.begin(),v.end(),a[i].r)-v.begin()+1;
 86     tot=v.size();  int ans = m;
 87 //    cout<<"!@#"<
 88     
 89     
 90     
 91     for (int i=1;i<=m;i++)
 92     {
 93     //    cout<<"i: "< 94     //    cout<
 95         memset(lazy,0,sizeof lazy);
 96         memset(tr,0,sizeof tr);
 97         change(1,1,tot,a[i].l,a[i].r,1);
 98     //    cout<
 99     
100         for (int j=i+1;j<=m;j++)
101         {
102             change(1,1,tot,a[j].l,a[j].r,-1);
103             
104             
105         }    
106         
107     //    cout<
108         if (query(1,1,tot,a[i].l,a[i].r)<=0)ans--;
109         change(1,1,tot,a[i].l,a[i].r,-1);
110     }
111      
112     cout<<ans;
113     
114     
115     
116 }

 

转载于:https://www.cnblogs.com/zhangbuang/p/10334370.html

你可能感兴趣的:(P3740 [HAOI2014]贴海报(离散化+线段树))