zoukankan      html  css  js  c++  java
  • [六省联考2017]相逢是问候 题解

    安利(:) 杂题选做

    洛谷 P3747 [六省联考2017]相逢是问候

    首先可以想到通过欧拉定理计算(.)

    不难发现只有前(log)次修改是有用的(,)那么直接维护就可以了(.)

    注意不要每次计算的时候直接调用快速幂(,)这样会多一个(log.)

    正确的姿势是对于每个(mod) (O(sqrt{2 imes mod}))预处理一下(c^x)(c^{mx}) (,)然后就可以做到(O(1))计算一个(c^x.)

    实现的好可以做到(O(nlog^2max(p,n)))

    代码(:)

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int N = 50005,D = 60;
    inline int calcphi(int n){
    	static int t,i,ans; t = n,ans = n;
    	for (i = 2; i * i <= n; ++i) if (t % i == 0){
    		while (!(t%i)) t /= i;
    		ans = ans / i * (i-1);
    	}
    	if (t > 1) ans = ans / t * (t-1);
    	return ans;
    }
    int P;
    int c;
    int p[D],cntp,c1[D][1<<15],c2[D][1<<15];
    inline int Mo(LL n,int p){ return n >= p ? (n % p + p) : n; }
    inline void init_c(){
    	int i,j;
    	for (i = 0; i <= cntp; ++i){
    		c1[i][0] = c2[i][0] = 1;
    		for (j = 1; j < 1<<15; ++j) c1[i][j] = Mo((LL)c1[i][j-1] * c,p[i]);
    		c2[i][1] = Mo((LL)c1[i][(1<<15)-1] * c,p[i]);
    		for (j = 2; j < 1<<15; ++j) c2[i][j] = Mo((LL)c2[i][j-1] * c2[i][1],p[i]);
    	}
    }
    inline int power(int n,int i){ return Mo((LL)c1[i][n&32767]*c2[i][n>>15],p[i]); }
    int n,m,a[N][D];
    inline int calc(int x,int cnt,int i){
    	if (!cnt) return Mo(x,p[i]); if (i == cntp) return c ? 1 : 0;
    	return power(calc(x,cnt-1,i+1),i);
    }
    int sum[N<<2],mn[N<<2];
    inline void up(int o){
    	mn[o] = min(mn[o<<1],mn[o<<1|1]);
    	sum[o] = sum[o<<1] + sum[o<<1|1];
    	if (sum[o] >= P) sum[o] -= P; 
    }
    inline void Build(int o,int l,int r){
    	mn[o] = 0; if (l == r){ sum[o] = a[l][0]; return; }
    	int mid = l+r>>1; Build(o<<1,l,mid); Build(o<<1|1,mid+1,r); up(o);
    }
    int ll,rr;
    inline void Add(int o,int l,int r){
    	if (mn[o] > cntp) return;
    	if (l == r){ ++mn[o],sum[o] = a[l][mn[o]]; return; } 
    	if (ll <= l && rr >= r){ int mid = l+r>>1; Add(o<<1,l,mid); Add(o<<1|1,mid+1,r); up(o); return; }
    	int mid = l+r>>1; if (ll <= mid) Add(o<<1,l,mid); if (rr > mid) Add(o<<1|1,mid+1,r); up(o);
    }
    int qans;
    inline void Ask(int o,int l,int r){
    	if (ll <= l && rr >= r){ qans = (qans + sum[o] >= P) ? (qans + sum[o] - P) : (qans + sum[o]); return; }
    	int mid = l+r>>1; if (ll <= mid) Ask(o<<1,l,mid); if (rr > mid) Ask(o<<1|1,mid+1,r);
    }
    int main(){
    	int i,j,op;
    	cin >> n >> m >> P >> c;
    	p[cntp = 0] = P; while (p[cntp] > 1) ++cntp,p[cntp] = calcphi(p[cntp-1]);
    	init_c();
    	for (i = 1; i <= n; ++i){
    		cin >> a[i][0];
    		for (j = 1; j <= cntp+1; ++j) a[i][j] = calc(a[i][0],j,0) % P;
    		a[i][0] %= P;
    	}
    	Build(1,1,n);
    	while (m--){
    		cin >> op >> ll >> rr;
    		if (op == 0) Add(1,1,n);
    		else qans = 0,Ask(1,1,n),cout << qans << '
    ';
    	}
    	return 0;
    }
    
  • 相关阅读:
    WIndows系统下mysql-noinstall安装配置
    Java compiler level does not match the version of the installed Java project facet.
    定时执行程序-Quartz简单实例
    win7安装ruby on rails
    ajax提交数据问题
    js打开新的链接下载文件
    Spring 3.2 ClassMetadataReadingVisitor 错误
    eclipse 错误: 找不到或无法加载主类
    sts 去掉启动的rss功能
    解决多线程下simpleDateFormat的安全问题
  • 原文地址:https://www.cnblogs.com/s-r-f/p/13584310.html
Copyright © 2011-2022 走看看