• 小花梨的数组


    https://acm.ecnu.edu.cn/contest/173/problem/E/

    区间操作,线段树;

    维护乘的次数和除的次数

    最后答案是,div和mul共同作用的结果,

    分两种来考虑,第一种是当前有足够多次1操作,所以当再来一次操作时,直接在此基础上进行修改,除就减,乘就加;

             第二种比较复杂,当前没有足够多的1操作,(我们这里要足够多的1操作时为了让进行除操作时容易)当当前要进行除操作时,被update区间的minprime可能会发生变化,

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 const int M=1e5+5;
      5 const int mod=1e9+7;
      6 struct node{
      7     int mul,div;
      8 }tree[M<<2];
      9 int  a[M];
     10 ll quick_pow(ll a,ll b){
     11     ll t=1;
     12     a%=mod;
     13     while(b){
     14         if(b&1)
     15             t=t*a,t%=mod;
     16         b>>=1;
     17         a=a*a%mod;
     18     }
     19     return t;
     20 }
     21 ll solve_div(ll x,int countt){
     22     if(x==1||countt==0)
     23         return x;
     24     ll m=sqrt(x+0.5);
     25     for(ll i=2;i<=m;i++){
     26         while(x%i==0){
     27             x/=i;
     28             countt--;
     29             if(x==1||countt==0)
     30                 return x;
     31         }
     32     }
     33     return 1;
     34 }
     35 int solve_mul(ll x,int countt){
     36     if(countt==0||x==1)
     37         return x;
     38     ll m=sqrt(x+0.5);
     39     int y=x;
     40     for(ll i=2;i<=m;i++)
     41         if(x%i==0){
     42             y=i;
     43             break;
     44         }
     45     x%=mod,y%=mod;
     46     return x*quick_pow(y,countt)%mod;
     47 }
     48 void pushdown(int root,int l,int r){
     49     if(tree[root].div==0&&tree[root].mul==0)
     50         return ;
     51     int lc=root<<1,rc=root<<1|1;
     52     int sign=min(tree[root].div,tree[lc].mul);
     53     tree[lc].mul-=sign;
     54     tree[lc].mul+=tree[root].mul;
     55     tree[lc].div+=tree[root].div-sign;
     56     
     57     sign=min(tree[root].div,tree[rc].mul);
     58     tree[rc].mul-=sign;
     59     tree[rc].mul+=tree[root].mul;
     60     tree[rc].div+=tree[root].div-sign;
     61     
     62     tree[root].div=tree[root].mul=0;
     63 }
     64 void update1(int L,int R,int root,int l,int r){
     65     if(L<=l&&r<=R){
     66         tree[root].mul++;
     67         return ;
     68     }
     69     pushdown(root,l,r);
     70     int midd=(l+r)>>1;
     71     if(L<=midd)
     72         update1(L,R,root<<1,l,midd);
     73     if(R>midd)
     74         update1(L,R,root<<1|1,midd+1,r);
     75 }
     76 void update2(int L,int R,int root,int l,int r){
     77     if(L<=l&&r<=R){
     78         if(tree[root].mul)
     79             tree[root].mul--;
     80         else
     81             tree[root].div++;
     82         return;
     83     }
     84     pushdown(root,l,r);
     85     int midd=(l+r)>>1;
     86     if(L<=midd)
     87         update2(L,R,root<<1,l,midd);
     88     if(R>midd)
     89         update2(L,R,root<<1|1,midd+1,r);
     90 }
     91 void query(int &div,int &mul,int pos ,int root,int l,int r){
     92     if(l==r){
     93         int sign=min(mul,tree[root].div);
     94         mul-=sign;
     95         div+=tree[root].div-sign;
     96         mul+=tree[root].mul;
     97         return ;
     98     }
     99     int midd=(l+r)>>1;
    100     if(pos<=midd)
    101         query(div,mul,pos,root<<1,l,midd);
    102     else
    103         query(div,mul,pos,root<<1|1,midd+1,r);
    104     int sign=min(mul,tree[root].div);
    105     mul-=sign;
    106     div+=tree[root].div-sign;
    107     mul+=tree[root].mul;
    108 }
    109 int main(){
    110     int n,m;
    111     scanf("%d%d",&n,&m);
    112     for(int i=1;i<=n;i++)
    113         scanf("%d",&a[i]); 
    114     /*for(int i=1;i<=n;i++){
    115         int flag=1;
    116         for(int j=2;j*j<=a[i];i++){
    117             if(a[i]%j==0){
    118                 minprime[i]=j;
    119                 flag=0;
    120                 break;
    121             }
    122         }
    123         if(flag)
    124             minprime[i]=i;
    125     }
    126     build(1,1,n);*/
    127     while(m--){
    128         int op;
    129         scanf("%d",&op);
    130         if(op==1){
    131             int x,y;
    132             scanf("%d%d",&x,&y);
    133             update1(x,y,1,1,n);
    134         }
    135         else if(op==2){
    136             int x,y;
    137             scanf("%d%d",&x,&y);
    138             update2(x,y,1,1,n);
    139         }
    140         else{
    141             int x;
    142             scanf("%d",&x);
    143             int LL=0,RR=0;
    144             query(LL,RR,x,1,1,n);
    145         //    cout<<"!!"<<endl;
    146             ll ans=0;
    147             ans=solve_div(a[x],LL);
    148             ans=solve_mul(ans,RR);
    149             printf("%lld
    ",ans%mod);
    150         }
    151     }
    152     return 0;
    153 }
    View Code
  • 相关阅读:
    一次网络IO优化的讨论
    服务器框架回顾
    一个小工具:DebugFile
    TPO-23 C2 Advice on choosing courses
    TPO-23 C1 Post a student announcement
    TPO-22 C2 Revise a music history paper
    TPO-22 C1 Complain about a biased article
    TPO-21 C2 Which elective courses to take
    TPO-20-Apply for the undergraduate research fund
    TPO-21 C1 Find a building for orientation
  • 原文地址:https://www.cnblogs.com/starve/p/10887971.html
Copyright © 2020-2023  润新知