csp-s模拟9697题解
题面:https://www.cnblogs.com/Juve/articles/11790223.html
96:
刚一看以为是水题,直接等差数列求和就好了,然后发现模数不是质数,还要1e18*1e18,就弃了,看T3,然后看错题了,打了个dij的40分暴力
然后看T1发现我好像会一个叫做慢速乘的东西(颓AlpaCa博客颓到的,现在应该是我的模板的第二个),然后就不用打高精了,
至于模数不是质数,因为答案一定是整数,而我的式子最终要除以4,所以就在乘之前先让它除,然后乘,然后T1就A了,
T2打了个n方暴力,骗到75,rk6还是近几次最好?可能是我太垃圾了。。。
T1:
上面都说过了,不再细说
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define int long long 6 using namespace std; 7 int x,y,xx,yy,tot=0; 8 int ans=0,mod; 9 int mul(int a,int b,int p){ 10 int res=0; 11 while(b){ 12 if(b&1) res=(res+a)%p; 13 a=(a+a)%p; 14 b>>=1; 15 } 16 return res; 17 } 18 signed main(){ 19 freopen("sum.in","r",stdin); 20 freopen("sum.out","w",stdout); 21 scanf("%lld%lld%lld%lld%lld",&x,&y,&xx,&yy,&mod); 22 int p=(x+y-1),q=(x+yy-1),pp=(xx+y-1),qq=(xx+yy-1); 23 int xkl1=(p+q+pp+qq),xkl2=(yy-y+1),xkl3=(xx-x+1); 24 while(tot<2&&xkl1%2==0){ 25 xkl1/=2; 26 ++tot; 27 } 28 while(tot<2&&xkl2%2==0){ 29 xkl2/=2; 30 ++tot; 31 } 32 while(tot<2&&xkl3%2==0){ 33 xkl3/=2; 34 ++tot; 35 } 36 ans=mul(mul(xkl2,xkl3,mod)%mod,xkl1,mod)%mod; 37 printf("%lld ",ans); 38 return 0; 39 }
T2:
就贪心地扫,二分最大不可行的位置,然而n2logn2复杂度不够优秀,我们倍增缩小二分的区间
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #define int long long 7 #define re register 8 using namespace std; 9 inline int read(){ 10 re int x=0;re char ch=getchar(); 11 while(ch<'0'||ch>'9') ch=getchar(); 12 while(ch>='0'&&ch<='9'){ 13 x=(x<<3)+(x<<1)+ch-'0'; 14 ch=getchar(); 15 } 16 return x; 17 } 18 const int MAXN=1e6+5; 19 int n,m,a[MAXN],b[MAXN],ans=0; 20 int staa[MAXN],stab[MAXN],topa,topb; 21 bool check(int l,int r){ 22 topa=topb=0; 23 for(int i=l;i<=r;++i) staa[++topa]=a[i],stab[++topb]=b[i]; 24 sort(staa+1,staa+topa+1),sort(stab+1,stab+topb+1); 25 int tot=0; 26 for(int i=1;i<=topa;++i){ 27 tot+=staa[i]*stab[i]; 28 if(tot>m) return 0; 29 } 30 return 1; 31 } 32 int get(int pos){ 33 int poss=1; 34 for(int i=1;;++i){ 35 poss=i; 36 if(pos+(1<<i)-1>n) break; 37 if(!check(pos,pos+(1<<i)-1)){ 38 poss=i; 39 break; 40 } 41 } 42 int l=pos+(1<<(poss-1))-1,r=pos+(1<<poss)-1; 43 int res=l; 44 while(l<=r){ 45 int mid=(l+r)>>1; 46 if(check(pos,mid)) res=max(res,mid),l=mid+1; 47 else r=mid-1; 48 } 49 return res+1; 50 } 51 signed main(){ 52 freopen("pair.in","r",stdin); 53 freopen("pair.out","w",stdout); 54 n=read(),m=read(); 55 for(re int i=1;i<=n;++i) a[i]=read(); 56 for(re int i=1;i<=n;++i) b[i]=read(); 57 for(re int i=1;i<=n;){ 58 i=get(i); 59 ++ans; 60 } 61 printf("%lld ",ans); 62 return 0; 63 }