BZOJ 4868-4873 题解
BZOJ4868
每个结束位置的最优值很显然具有单调性,三分,再讨论一下就好了.
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define FILE "exam" 5 #define up(i,j,n) for(int i=j;i<=n;i++) 6 #define db long double 7 #define pii pair<int,int> 8 #define pb push_back 9 template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;} 10 template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;} 11 template<class T> inline T squ(T a){return a*a;} 12 const int maxn=105000+10,inf=1e9+10,mod=201314; 13 ll read(){ 14 ll x=0,f=1,ch=getchar(); 15 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 16 while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); 17 return x*f; 18 } 19 db A,B,C; 20 ll a[maxn],b[maxn],d[maxn],n,m; 21 db check(ll s){ 22 db ans=0; 23 memcpy(d,b,sizeof(d)); 24 if(A<B){ 25 int l=1,r=m; 26 while(l<r){ 27 if(d[r]<s||d[l]>s)break; 28 if(d[r]-s>s-d[l])ans+=A*(s-d[l]),d[r]-=s-d[l],d[l]=s,l++; 29 else ans+=A*(d[r]-s),d[l]+=d[r]-s,d[r]=s,r--; 30 } 31 for(int i=m;i>=1;i--) 32 if(d[i]>s)ans+=B*(d[i]-s); 33 for(int i=1;i<=n;i++) 34 if(a[i]<s)ans+=C*(s-a[i]); 35 return ans; 36 } 37 else { 38 for(int i=1;i<=m;i++)if(d[i]>s)ans+=B*(d[i]-s); 39 for(int i=1;i<=n;i++) 40 if(a[i]<s)ans+=C*(s-a[i]); 41 return ans; 42 } 43 } 44 int main(){ 45 freopen(FILE".in","r",stdin); 46 freopen(FILE".out","w",stdout); 47 A=read(),B=read(),C=read(); 48 n=read(),m=read(); 49 ll left=inf,right=-inf; 50 up(i,1,n)a[i]=read(),cmin(left,a[i]); 51 up(i,1,m)b[i]=read(),cmax(right,b[i]); 52 sort(b+1,b+m+1); 53 sort(a+1,a+n+1); 54 while(right-left>3){ 55 int mid1=(left+left+right)/3; 56 int mid2=(left+right+right)/3; 57 if(check(mid1)>check(mid2))left=mid1; 58 else right=mid2; 59 } 60 db Ans=(ll)1e18; 61 for(int i=left;i<=right;i++) 62 cmin(Ans,check(i)); 63 printf("%.0Lf ",Ans); 64 return 0; 65 }
BZOJ4869
看到这道题后我想到了某道同样是一堆幂的神题,尽管我没写过...
正确做法是EX欧拉定理+线段树,我会欧拉定理,但我不知道什么是EX欧拉定理.
请自行百度,(尽管你baidu不到).
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define int long long 4 #define FILE "verbinden" 5 #define up(i,j,n) for(int i=j;i<=n;++i) 6 #define db long double 7 #define pii pair<int,int> 8 #define pb push_back 9 template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;} 10 template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;} 11 template<class T> inline T squ(T a){return a*a;} 12 const int maxn=210000+10,inf=1e9+10; 13 int read(){ 14 int x=0,f=1,ch=getchar(); 15 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 16 while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); 17 return x*f; 18 } 19 int n,m,mod,C; 20 int a[maxn]; 21 int op[maxn],x[maxn],y[maxn]; 22 int fi[maxn]; 23 int getfi(int n){ 24 int m=sqrt(n*1.0)+1,ans=1; 25 if(n==1)return 1; 26 for(int i=2;i<=m;i++){ 27 if(n%i==0)ans=ans*(i-1),n/=i; 28 while(n%i==0){ 29 ans=ans*(i); 30 n/=i; 31 } 32 if(n==1)break; 33 } 34 if(n!=1)ans=ans*(n-1); 35 return ans; 36 } 37 int sum[maxn],siz[maxn],ci[maxn],tot=0; 38 void updata(int o){ 39 sum[o]=(sum[o<<1]+sum[o<<1|1])%mod; 40 siz[o]=siz[o<<1]+siz[o<<1|1]; 41 } 42 void build(int l,int r,int o){ 43 if(l==r){ 44 sum[o]=a[l]; 45 siz[o]=1; 46 return; 47 } 48 int mid=(l+r)>>1; 49 build(l,mid,o<<1); 50 build(mid+1,r,o<<1|1); 51 updata(o); 52 } 53 bool flag=0; 54 int qpow(int a,int b,int mod){ 55 int ans=1; 56 bool f0=0; 57 while(b){ 58 if(b&1){ 59 if(ans*a>=mod||f0)flag=1; 60 ans=ans*a%mod; 61 } 62 if(squ(a)>=mod)f0=1; 63 a=squ(a)%mod; 64 b>>=1; 65 } 66 return ans; 67 } 68 int k(int a,int mod){ 69 if(a>=mod)return a%mod+mod; 70 else return a; 71 } 72 void change(int l,int r,int L,int R,int o){ 73 if(l>R||r<L)return ; 74 if(l==r){ 75 if(siz[o]){ 76 ci[l]++; 77 sum[o]=k(a[l],fi[ci[l]]); 78 for(int j=ci[l]-1;j>=0;j--){ 79 flag=0; 80 sum[o]=qpow(C,sum[o],fi[j]); 81 if(flag)sum[o]+=fi[j]; 82 } 83 if(ci[l]==tot)siz[o]=0; 84 } 85 return; 86 } 87 int mid=(l+r)>>1; 88 if(l>=L&&r<=R){ 89 if(siz[o<<1])change(l,mid,L,R,o<<1); 90 if(siz[o<<1|1])change(mid+1,r,L,R,o<<1|1); 91 updata(o); 92 return; 93 } 94 change(l,mid,L,R,o<<1); 95 change(mid+1,r,L,R,o<<1|1); 96 updata(o); 97 } 98 int query(int l,int r,int L,int R,int o){ 99 if(l>R||r<L)return 0; 100 if(l>=L&&r<=R)return sum[o]; 101 int mid=(l+r)>>1; 102 return (query(l,mid,L,R,o<<1)+query(mid+1,r,L,R,o<<1|1))%mod; 103 } 104 main(){ 105 freopen(FILE".in","r",stdin); 106 freopen(FILE".out","w",stdout); 107 n=read(),m=read(),mod=read(),C=read(); 108 up(i,1,n)a[i]=read(); 109 up(i,1,m)op[i]=read(),x[i]=read(),y[i]=read(); 110 build(1,n,1); 111 fi[0]=mod; 112 for(int i=1;i<=m;i++){ 113 fi[i]=getfi(fi[i-1]); 114 if(fi[i]==1){ 115 fi[i+1]=1; 116 tot=i+1; 117 break; 118 } 119 } 120 up(i,1,m){ 121 if(op[i]==0)change(1,n,x[i],y[i],1); 122 if(op[i]==1)printf("%d ",query(1,n,x[i],y[i],1)); 123 } 124 return 0; 125 }