zoukankan      html  css  js  c++  java
  • [cf1379F]Chess Strikes Back

    考虑将$(2i-1,2j-1)$和$(2i,2j)$缩为一个点,记作$(i,j)$

    对于每一个点,只能选$(2i-1,2j-1)$或$(2i,2j)$(显然不能都选),而这样恰好为$nm$个,因此必须要至少选择一个

    对于每一个点,障碍的状态分为以下几类:

    1.无障碍,这类点暂时不考虑

    2.都有障碍,若存在此类点必然不合法

    3.有一个障碍,分两类讨论:

    (1)$(2i-1,2j-1)$上有障碍,即这个点只能选$(2i,2j)$,考虑$(i+1,j)$和$(i,j+1)$,也只能选这个点,因此即对于其右下角的点,都要选$(2i,2j)$;

    (2)$(2i,2j)$上有障碍,类似的,对于其左上角的点,都要选$(2i-1,2j-1)$

    矛盾在于存在一个点$(i_{1},j_{1})$在$(2i_{1}-1,2j_{1}-1)$上有障碍,$(i_{2},j_{2})$在$(2i_{2},2j_{2})$上有障碍,且满足$i_{1}le i_{2}$、$j_{1}le j_{2}$,那么对于$([i_{1},i_{2}],[j_{1},j_{2}])$这个矩形就无解了

    (其实第2类也可以看作此类情况,即$i_{1}=i_{2}$且$j_{1}=j_{2}$)

    通过set,可以求出对于所有$i$,在$(2i-1,2j-1)$上有障碍的最小的$j$和在$(2i,2j)$上有障碍的最大的$j$

    对于插入可以很好的支持,即判断新来的点是否会产生即可(通过线段树维护第一个前缀最小值以及第二个后缀最大值),那么删除通过线段树分治即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 200005
     4 #define L (k<<1)
     5 #define R (L+1)
     6 #define mid (l+r>>1)
     7 #define pii pair<int,int>
     8 #define mp make_pair
     9 #define fi first
    10 #define se second
    11 map<int,int>mat[N<<1];
    12 map<int,int>::iterator it;
    13 multiset<int>s1[N],s2[N]; 
    14 vector<pii>v[N<<2];
    15 pii f[N<<2];
    16 int n,m,q,x,y,ans[N];
    17 void add(int k,int l,int r,int x,int y,pii z){
    18     if ((l>y)||(x>r))return;
    19     if ((x<=l)&&(r<=y)){
    20         v[k].push_back(z);
    21         return;
    22     }
    23     add(L,l,mid,x,y,z);
    24     add(R,mid+1,r,x,y,z);
    25 }
    26 pii merge(pii x,pii y){
    27     return mp(min(x.fi,y.fi),max(x.se,y.se));
    28 }
    29 pii get(int k){
    30     int x=m+1,y=0;
    31     if (s1[k].size())x=(*s1[k].begin());
    32     if (s2[k].size())y=(*--s2[k].end());
    33     return mp(x,y);
    34 }
    35 void update(int k,int l,int r,int x){
    36     if (l==r){
    37         f[k]=get(x);
    38         return;
    39     }
    40     if (x<=mid)update(L,l,mid,x);
    41     else update(R,mid+1,r,x);
    42     f[k]=merge(f[L],f[R]);
    43 }
    44 pii query(int k,int l,int r,int x,int y){
    45     if ((l>y)||(x>r))return mp(m+1,0);
    46     if ((x<=l)&&(r<=y))return f[k];
    47     return merge(query(L,l,mid,x,y),query(R,mid+1,r,x,y));
    48 }
    49 void dfs(int k,int l,int r){
    50     if (!ans[0])return;
    51     for(int i=0;i<v[k].size();i++){
    52         x=v[k][i].fi,y=v[k][i].se;
    53         if (y&1){
    54             s1[(x+1)/2].insert((y+1)/2);
    55             if (query(1,1,n,(x+1)/2,n).se>=(*s1[(x+1)/2].begin()))ans[0]=0;
    56         }
    57         else{
    58             s2[x/2].insert(y/2);
    59             if (query(1,1,n,1,x/2).fi<=(*--s2[x/2].end()))ans[0]=0;
    60         }
    61         update(1,1,n,(x+1)/2);
    62     }
    63     if (l==r)ans[l]=ans[0];
    64     else{
    65         dfs(L,l,mid);
    66         dfs(R,mid+1,r);
    67     }
    68     for(int i=0;i<v[k].size();i++){
    69         x=v[k][i].fi,y=v[k][i].se;
    70         if (y&1)s1[(x+1)/2].erase(s1[(x+1)/2].find((y+1)/2));
    71         else s2[x/2].erase(s2[x/2].find(y/2));
    72         update(1,1,n,(x+1)/2);
    73     }
    74     ans[0]=1;
    75 }
    76 int main(){
    77     scanf("%d%d%d",&n,&m,&q);
    78     for(int i=1;i<=q;i++){
    79         scanf("%d%d",&x,&y);
    80         if (!mat[x][y])mat[x][y]=i;
    81         else{
    82             add(1,1,q,mat[x][y],i-1,mp(x,y));
    83             mat[x][y]=0;
    84         }
    85     }
    86     for(int i=1;i<=2*n;i++)
    87         for(it=mat[i].begin();it!=mat[i].end();it++)
    88             if ((*it).se)add(1,1,q,(*it).se,q,mp(i,(*it).fi));
    89     for(int i=1;i<=n;i++)update(1,1,n,i);
    90     ans[0]=1;
    91     dfs(1,1,q);
    92     for(int i=1;i<=q;i++)
    93         if (ans[i])printf("YES
    ");
    94         else printf("NO
    ");
    95 }
    View Code
  • 相关阅读:
    jQuery中时间戳和日期的相互转换
    jquery append 方法应用
    MySQL中实现连续日期内数据统计,缺省天数0补全
    jQuery通过ajax请求php遍历json数组到table中的代码
    sql相同表不同查询条件合并显示
    paginate()出来的数据怎样循环插入数据?
    使用paginate分页后数据处理
    ThinkPhp3.2.3 使用phpExcel导入数据
    判断时间戳是星期几
    英文加数字升序/降序
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14301760.html
Copyright © 2011-2022 走看看