zoukankan      html  css  js  c++  java
  • codeforces 1114F

    虽然挺好想,但是很难写。
    还是第一次写带标记永久化的区间操作,区间查询线段树。
    修改时一直根据实际长度改值,被包含时改标记。
    查询时被包含算值,否则一直根据实际长度算标记。

    #include <bits/stdc++.h>
    using namespace std;
    const int M=1e9+7;
    const int C=62;
    typedef long long lll;
    const int N=400010;
    int a[N];
    struct node{
        int val,tag;
        lll app,pag;
    }T[1<<20];
    int p[C],inv[C];
    lll rep(int x){
        lll ret=0;
        for (int i=0; i<C; ++i) if (x%p[i]==0) ret|=1ll<<i;
        return ret;
    }
    bool b[400];
    int fp(int x,int y){
        int ret=1;
        for (; y; y>>=1,x=(lll)x*x%M) if (y&1) ret=(lll)ret*x%M;
        return ret;
    }
    int ll,rr,cc,n,q;
    lll cf;
    void build(int ind,int l,int r){
        T[ind].tag=1;
        if (l==r){
    	T[ind].val=a[l];
    	T[ind].app=rep(a[l]);
    	return;
        }
        int mid=(l+r)>>1;
        build(ind<<1,l,mid);
        build(ind<<1|1,mid+1,r);
        T[ind].app=T[ind<<1].app|T[ind<<1|1].app;
        T[ind].val=(lll)T[ind<<1].val*T[ind<<1|1].val%M;
    }
    void update(int ind,int l,int r){
        T[ind].app|=cf;
        lll d=fp(cc,min(r,rr)-max(l,ll)+1);
        T[ind].val=T[ind].val*d%M;
        if (ll<=l&&r<=rr){
    	//cerr<<"CD"<<cc<<" "<<l<<" "<<r<<endl;
    	T[ind].tag=(lll)T[ind].tag*cc%M;
    	T[ind].pag|=cf;
    	return;
        }
        int mid=(l+r)>>1;
        if (ll<=mid) update(ind<<1,l,mid);
        if (mid<rr) update(ind<<1|1,mid+1,r);
    }
    void ask(int ind,int l,int r){
        if (ll<=l&&r<=rr){
    	//cerr<<l<<" "<<r<<" "<<T[ind].val<<endl;
    	cc=(lll)T[ind].val*cc%M;
    	cf|=T[ind].app;
    	return;
        }
        cc=(lll)fp(T[ind].tag,(min(r,rr)-max(l,ll)+1))*cc%M;
        cf|=T[ind].pag;
        int mid=(l+r)>>1;
        if (ll<=mid) ask(ind<<1,l,mid);
        if (mid<rr) ask(ind<<1|1,mid+1,r);
    }
    int main(){
        int pnum=0;
        for (int i=2; i<=300; ++i){
    	if (b[i]) continue;
    	p[pnum++]=i;
    	for (int j=i*i; j<=300; j+=i)
    	    b[j]=1;
        }
        for (int i=0; i<pnum; ++i) inv[i]=fp(p[i],M-2);
        scanf("%d%d",&n,&q);
        for (int i=1; i<=n; ++i){
    	scanf("%d",&a[i]);
        }
        build(1,1,n);
        for (int i=1; i<=q; ++i){
    	char s[10];
    	scanf("%s%d%d",s,&ll,&rr);
    	if (s[0]=='T'){
    	    cc=1; cf=0;
    	    ask(1,1,n);
    	    //cerr<<"CC"<<cc<<endl;
    	    for (int i=0; i<C; ++i) if ((cf>>i)&1) cc=(lll)cc*inv[i]%M*(p[i]-1)%M;
    	    cout<<cc<<'
    ';
    	}
    	else{
    	    scanf("%d",&cc);
    	    cf=rep(cc);
    	    update(1,1,n);
    	}
        }
    }
    

    快速幂预处理分类讨论一下,应该也可一个(log)

  • 相关阅读:
    webMagic学习笔记 主页
    maven 听视频笔记
    idea如何做到多模块开发项目 收藏整理
    JAVA 增删改查接口命名规范(dao层与 service 层
    mybatis 自学笔记
    nginx学习主页导航
    用 async/await 来处理异步
    若依:SysUserMapper.xml 分析
    idea 创建多模块项目子模块为灰色
    Maven多模块开发遇到的错误 -- Maven的子模块变成灰色
  • 原文地址:https://www.cnblogs.com/Yuhuger/p/10367171.html
Copyright © 2011-2022 走看看