其他分享
首页 > 其他分享> > 防线

防线

作者:互联网

防线

现在有一个\(1\times 2^{31}\)的网格图,位置编号\(0\sim 2^{31}-1\),给出n个三元组,第i个三元组用\((s_i,t_i,d_i)\)表示,意义为从位置\(s_i\)开始,\(s_i,s_i+d_i,...,s_i+(k-1)d_i\leq e_i\)都放上一颗棋子,其中只有最多一个网格中有奇数个棋子,询问这个网格的位置,\(n\leq 200000\)。

考虑二分,注意到二分位置的话,不存在单调性,也无法判断是否有更优解,于是考虑二分一段区间,设二分区间为\([l,r]\),取中间点\(mid=l+r>>1\),显然现在划分成两段区间\([l,mid];[mid+1,r]\),哪一段里的棋子为奇数个,就可以二分下去。

现在关键是如何确定一段区间\([l,r]\)中有的棋子数目,对于一个三元组\((s_i,t_i,d_i)\)而言,显然我们应该取两个区间的交集来计算,记为\([L,R]\),显然\(L=\max(l,s_i),R=\min(r,t_i)\),而三元组的含义,类似剩余类(多个三元组组成一个剩余系,当然不准确,而且也不可能是完全剩余系或者最简剩余系),实际上是循环节\(s_i\% d_i+kd_i\)在\([s_i,t_i]\)中出现的次数,类比过来,也就是求这个循环节在\([L,R]\)中出现的次数,显然可以拆成求\([0,L-1],[0,R]\)的循环节出现的次数,后者减去前者就是答案了。

以\([0,R]\)出现循环节k次为例,有\(s_i\%d_i+(k-1)d_i\leq R\),于是我们有\(k\leq [\frac{R-s_i\%d_i+d_i}{d_i}]\)(一定记住是移完项以后再向下取整,提前向下取整答案是wa的)。

因此就可以再在\(nlog(n)\)处理出答案。

参考代码:

#include <iostream>
#include <cstdio>
#define il inline
#define ri register
#define Size 200500
using namespace std;
int s[Size],e[Size],d[Size],n;
il void read(int&);
il bool check(int,int);
il int min(int,int),max(int,int);
int main(){
    int lsy;read(lsy);
    while(lsy--){read(n);
        for(int i(1);i<=n;++i)
            read(s[i]),read(e[i]),read(d[i]);
        int l(0),r(1e9),mid,ans(0);
        if(check(l,r)){while(l<r){mid=l+r>>1;
                if(check(l,mid))r=mid;else l=mid+1;
            }for(int i(1);i<=n;++i)
                 if(s[i]<=l&&l<=e[i]&&l%d[i]==s[i]%d[i])++ans;
            printf("%d %d\n",l,ans);
        }else puts("There's no weakness.");
    }
    return 0;
}
il int max(int a,int b){
    return a>b?a:b;
}
il int min(int a,int b){
    return a<b?a:b;
}
il bool check(int l,int r){int ans(0);
    for(int i(1),L,R;i<=n;++i){
        L=max(l,s[i])-1,R=min(r,e[i]);if(L>=R)continue;
        ans+=((R-s[i]%d[i]+d[i])/d[i]-(L-s[i]%d[i]+d[i])/d[i]);
    }return ans&1;
}
il void read(int &x){
    x^=x;ri char c;while(c=getchar(),c<'0'||c>'9');
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
}

标签:二分,int,防线,mid,三元组,read,il
来源: https://www.cnblogs.com/a1b3c7d9/p/11227676.html