HDU 4768:Flyer(等差数列求模和运算)

来源:互联网 发布:天下3男捏脸大赛数据 编辑:程序博客网 时间:2024/06/05 11:48
题意:n个社团派发传单,有a,b,c三个参数,派发的规则是,派发给序号为a,a+c....a+k*c,序号要求是小于等于b
这其中,有一个学生只收到了奇数传单,要求找出这个学生的编号与得到的传单数目

思路:每行用模板异或
#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <cmath>#include <vector>#include <set>#include <list>#include <queue>#include <map>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-3#define maxn 1000100#define MOD 1000000007int n,k;long long a[20020],b[20020],c[20020];int tt = 1;long long Get(long long dis, long long l, long long P, long long number){   // cout << tt++ << endl;    long long ret = 0;    ret += (l / P) * number;    l %= P;    ret += (dis / P) * number * (number - 1) / 2;    dis %= P;    if (dis * number + l < P)        return ret;    else        return ret + Get(P, (dis * number + l) % P, dis, (dis * number + l) / P);}long long GetYiHuo(long long l, long long r, long long dis)  //以x开始, y为结束, dis为等差 连续异或{    //number为计算的个数    long long number = (r - l) / dis+1, ans = 0, Sum, P = 1;    int len = 32;   ///位数,可以多不能少    for (long long i = 1; i <= len; i++)    {        tt = 1;        Sum = Get(dis, l, P, number);        if (Sum & 1)            ans += P;        P <<= 1;    }    return ans;}int main(){    int t,C = 1;    //scanf("%d",&t);    while(scanf("%d",&n) != EOF)    {        long long ans = 0;        for(int i = 0; i < n; i++)        {            scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);            ans ^= GetYiHuo(a[i],b[i],c[i]);        }        int cnt = 0;        for(int i = 0; i < n; i++)        {            if(ans > b[i] || ans < a[i])                continue;            if((ans-a[i])%c[i] == 0)                cnt++;        }        if(ans && cnt)            printf("%lld %d\n",ans,cnt);        else            printf("DC Qiang is unhappy.\n");    }    return 0;}


0 0
原创粉丝点击