hdu 5063 操作逆推+mul每次要*2%(modo - 1)

http://acm.hdu.edu.cn/showproblem.php?pid=5063

只有50个询问,50个操作逆推回去即可,注意mul每次要*2%(modo - 1)因为是指数!

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <set>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
typedef long long LL;

int n,m;
const double pi = acos ( -1.0 ) ;
const LL modo = 1000000007;
int op[100005],op_n;
LL ans[55];
int ans_n;
LL quick_pow(LL a,int b)
{
    LL c = 1;
    while(b){
        if(b&1)
            c = (c*a)%modo;
        b>>=1;
        a = (a*a)%modo;
    }
    return c;
}
LL gao(LL x)
{
    int mul = 1;
    for(int i = op_n - 1;i >= 0;--i){
        if(op[i] == 1){
            //  1,3,5->1,2,3
            //  2,4,6->4,5,6

            //  1,3,5,7->1,2,3,4
            //  2,4,6->5,6,7
            if(x <= (n+1)/2)
                x = x*2 - 1;
            else
                x = (x - (n+1)/2)<<1;
        }
        else if(op[i] == 2){
            x = n + 1 - x;
        }
        else{
            mul = (mul*2)%(modo-1);
        }
    }
    return quick_pow(x,mul);
}
void work()
{
    op_n = ans_n = 0;
    LL x;
    char q[2];
    while(m--){
        scanf("%s%I64d",q,&x);
        if(q[0] == 'O'){
            op[op_n++] = (int)x;
        }else{
            ans[ans_n++] = gao(x);
        }
    }
    for(int i = 0;i < ans_n;++i)
        printf("%I64d\n",ans[i]);
    return;
}
int main () {
    int T;
    RD(T);
    while(T--){
        RD2(n,m);
        work();
    }
    return 0 ;
}


你可能感兴趣的:(HDU)