题面:https://www.cnblogs.com/Juve/articles/11479415.html

T1:高精度gcd,其实不用写高精度取模,gcd还有一种求法

int gcd(int a,int b){
if(a==b) return a;
if(a%2==0&&b%2==0) return 2*gcd(a/2,b/2);
if(a%2==0) return gcd(a/2,b);
if(b%2==0) return gcd(a,b/2);
if(a<b) swap(a,b);
return gcd(a-b,b);
}

然后愉快地AC

#include<iostream>
#include<cstdio>
#include<cstring>
#define int long long
#define re register
using namespace std;
int t,la,lb,c[105];
char a[105],b[105];
struct bigint{
int m[105];
bigint(){memset(m,0,sizeof(m));}
inline friend void operator *= (bigint &a,re int b){
int x=0;
for(re int i=1;i<=a.m[0];i++){
re int y=a.m[i]*b+x;
a.m[i]=y%10;
x=y/10;
}
while(x){
a.m[++a.m[0]]=x%10;
x/=10;
}
}
inline friend void operator /= (bigint &a,re int b){
re int x=0;
for(re int i=a.m[0];i>=1;i--){
x+=a.m[i];
a.m[i]=x/b;
x%=b;
x*=10;
}
while(a.m[a.m[0]]==0&&a.m[0]>1)
a.m[0]--;
}
inline friend bigint operator - (bigint a,bigint b){
bigint c;
re int i=1;
while((i<=a.m[0])||(i<=b.m[0])){
if(a.m[i]<b.m[i]){
a.m[i]+=10;
a.m[i+1]--;
}
c.m[i]=a.m[i]-b.m[i];
i++;
}
while(c.m[i]==0&&i>1)
i--;
c.m[0]=i;
return c;
}
inline friend bool operator >= (bigint a,bigint b){
if(a.m[0]>b.m[0]) return 1;
if(a.m[0]<b.m[0]) return 0;
for(int i=a.m[0];i>=1;--i){
if(a.m[i]==b.m[i]) continue;
return a.m[i]>b.m[i];
}
return 1;
}
inline friend bool operator == (bigint a,bigint b){
int p=a.m[0],q=b.m[0];
if(p!=q) return 0;
for(int i=1;i<=p;++i){
if(a.m[i]!=b.m[i]) return 0;
}
return 1;
}
inline friend void print(bigint a){
for(re int i=a.m[0];i>=1;i--)
printf("%lld",a.m[i]);
puts("");
}
}n,m;
bool judge(bigint a){
int p=a.m[1];
//cout<<p<<endl;
if(p%2==0) return 1;
return 0;
}
bool check(bigint a,bigint b){
//print(a),print(b);
if(a==b){
if(a.m[0]==1&&a.m[1]==1) return 1;
else return 0;
}
bool p=judge(a),q=judge(b);
//cout<<p<<' '<<q<<endl;
if(p&&q) return 0;
if(p){
a/=2;
return check(a,b);
}
if(q){
b/=2;
return check(a,b);
}
if(!(a>=b)) swap(a,b);
return check(a-b,b);
}
int gcd(int a,int b){
if(a==b) return a;
if(a%2==0&&b%2==0) return 2*gcd(a/2,b/2);
if(a%2==0) return gcd(a/2,b);
if(b%2==0) return gcd(a,b/2);
if(a<b) swap(a,b);
return gcd(a-b,b);
}
signed main(){
scanf("%lld",&t);
while(t--){
memset(n.m,0,sizeof(n.m));
memset(m.m,0,sizeof(m.m));
scanf("%s %s",a+1,b+1);
la=strlen(a+1),lb=strlen(b+1);
n.m[0]=la,m.m[0]=lb;
for(int i=1;i<=la;++i) n.m[la-i+1]=a[i]-'0';
for(int i=1;i<=lb;++i) m.m[lb-i+1]=b[i]-'0';
if(check(n,m)==1) puts("Yes");
else puts("No");
}
return 0;
}

T2:

正解$O(n)$,数状数组卡常可A

$sum_i$表示前缀和

我们对于每一个i,求出$sum_i-sum_{j-1}>\frac{i-j+1}{2}(j<i)$的数量

然后就转化成了$2sum_i-i>2sum_{j-1}-(j-1)$,然后数状数组即可

然后用总区间减去不合法的即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define re register
using namespace std;
const int MAXN=5e6+5;
int n,sum0[MAXN],sum1[MAXN],sum2[MAXN],sum[MAXN];
char a[MAXN],ch;
long long ans=0;
struct BIT_tree{
int c[MAXN*3];
inline int lowbit(re int x){
return x&-x;
}
inline void add(re int pos){
//cout<<pos<<' '<<val<<endl;
while(pos<=2*n){
++c[pos];
pos+=lowbit(pos);
//cout<<pos<<endl;
}
}
inline int query(re int pos){
re int res=0;
while(pos>0){
res+=c[pos];
pos-=lowbit(pos);
}
return res;
}
}tr[3];
signed main(){
//freopen("ex4.in","r",stdin);
scanf("%d",&n);
scanf("%s",a+1);
for(re int i=1;i<=n;++i){
sum0[i]=sum0[i-1],sum1[i]=sum1[i-1],sum2[i]=sum2[i-1];
if(a[i]=='0') ++sum0[i];
if(a[i]=='1') ++sum1[i];
if(a[i]=='2') ++sum2[i];
tr[0].add(2*sum0[i-1]-i+n+2);
ans+=tr[0].query(2*sum0[i]-i+n);
tr[1].add(2*sum1[i-1]-i+n+2);
ans+=tr[1].query(2*sum1[i]-i+n);
tr[2].add(2*sum2[i-1]-i+n+2);
ans+=tr[2].query(2*sum2[i]-i+n);
}
printf("%lld\n",(1ll*n*(n+1)/2)-ans);
return 0;
}

%%正解大佬gby

#include <iostream>
#include <cstring>
#include <cstdio>
#define lowbit(x) ((x)&(-(x)))
#define N 5555555
#define LL long long
#define pre(i,j) pre[(i)+nn][j]
#define tb(i,j) tb[(i)+nn][j] using namespace std; int nn,pre[2*N][3],tb[2*N][3];
char arr[N];
int dat[N][3];
LL ans;
int main(){
scanf("%d",&nn);
scanf("%s",arr+1);
for(int i=1;i<=nn;i++){
dat[i][0]=dat[i-1][0]+1;
dat[i][1]=dat[i-1][1]+1;
dat[i][2]=dat[i-1][2]+1;
dat[i][arr[i]-'0']-=2;
}
/*for(int i=0;i<=2;i++){
printf("%d:",i);
for(int j=1;j<=nn;j++)
cout<<dat[j][i]<<" ";
cout<<endl;
}*/
ans=(long long)nn*(nn+1)/2;
//cout<<ans<<endl;
pre(0,0)++,pre(0,1)++,pre(0,2)++;
tb(0,0)++ ,tb(0,1)++, tb(0,2)++;
static int lst[3];
for(int i=1;i<=nn;i++){
for(int k=0;k<=2;k++){
tb(dat[i][k],k)++;
if(dat[i][k]==lst[k]+1){
pre(dat[i][k],k)=pre(lst[k],k)+tb(dat[i][k],k);
}
else {//dat[i][k]==lst[k]-1
pre(dat[i][k],k)=pre(dat[i][k]-1,k)+tb(dat[i][k],k);
pre(lst[k],k)=pre(dat[i][k],k)+tb(lst[k],k);
}
ans-=i+1-pre(dat[i][k],k);
// cout<<k<<":"<<i+1-pre(dat[i][k],k)<<endl;
}
lst[0]=dat[i][0];
lst[1]=dat[i][1];
lst[2]=dat[i][2];
/*for(int i=0;i<=2;i++){
printf("%d:",i);
for(int j=-nn;j<=nn;j++)
cout<<pre(j,i)<<" ";
cout<<endl;
}*/
}
cout<<ans<<endl;
}

T3:

wqs二分

首先一个暴力dp:

#include<iostream>
#include<cstdio>
#include<cstring>
#define re register
using namespace std;
const int MAXN=100005;
int n,a,b;
double p[MAXN],q[MAXN],ans=0.0,f[2][605][605];
inline double max(re double a,re double b){
return a>b?a:b;
}
signed main(){
while(~scanf("%d%d%d",&n,&a,&b)){
//memset(f,0,sizeof(f));
for(re int i=1;i<=n;++i) scanf("%lf",&p[i]);
for(re int i=1;i<=n;++i) scanf("%lf",&q[i]);
ans=0.0;
//f[0][0][0]=0;
memset(f[0],0,sizeof(f[0]));
for(re int i=1;i<=n;++i){
for(re int j=0;j<=min(a,n);++j){
for(re int k=0;k<=min(b,n);++k){
f[i&1][j][k]=f[i&1^1][j][k];
if(j!=0) f[i&1][j][k]=max(f[i&1][j][k],f[i&1^1][j-1][k]+p[i]);
if(k!=0) f[i&1][j][k]=max(f[i&1][j][k],f[i&1^1][j][k-1]+q[i]);
if(j!=0&&k!=0)
f[i&1][j][k]=max(f[i&1][j][k],f[i&1^1][j-1][k-1]+p[i]+q[i]-p[i]*q[i]);
}
}
}
printf("%0.3lf\n",f[n&1][a][b]);
}
return 0;
}

然后优化:

#include<iostream>
#include<cstdio>
#include<cstring>
#define re register
#define eps 1e-8
using namespace std;
const int MAXN=100005;
int n,a,b;
double p[MAXN],q[MAXN],ans=0.0,l,r,L,R,f[MAXN],fa[MAXN],fb[MAXN];
inline double max(re double a,re double b){
return a>b?a:b;
}
bool judge(double na,double nb){
memset(f,0,sizeof(f));
memset(fa,0,sizeof(fa));
memset(fb,0,sizeof(fb));
for(int i=1;i<=n;i++){
f[i]=f[i-1],fa[i]=fa[i-1],fb[i]=fb[i-1];
if(f[i-1]+p[i]>f[i]+na)
f[i]=f[i-1]+p[i]-na,fa[i]=fa[i-1]+1,fb[i]=fb[i-1];
if(f[i-1]+q[i]>f[i]+nb)
f[i]=f[i-1]+q[i]-nb,fb[i]=fb[i-1]+1,fa[i]=fa[i-1];
if(f[i-1]+p[i]+q[i]-p[i]*q[i]>f[i]+na+nb)
f[i]=f[i-1]+p[i]+q[i]-p[i]*q[i]-na-nb,fa[i]=fa[i-1]+1,fb[i]=fb[i-1]+1;
}
return fb[n]>b;
}
bool check(double na){
L=0.0,R=1.0;
while(R-L>eps){
double mid=(L+R)/2.0;
if(judge(na,mid)) L=mid;
else R=mid;
}
judge(na,R);
return fa[n]>a;
}
signed main(){
while(~scanf("%d%d%d",&n,&a,&b)){
for(re int i=1;i<=n;++i) scanf("%lf",&p[i]);
for(re int i=1;i<=n;++i) scanf("%lf",&q[i]);
l=0.0,r=1.0;
ans=0.0;
memset(f,0,sizeof(f));
memset(fa,0,sizeof(fa));
memset(fb,0,sizeof(fb));
while(r-l>eps){
double mid=(l+r)/2.0;
if(check(mid)) l=mid;
else r=mid;
}
judge(r,R);
printf("%0.5lf\n",f[n]+a*r+b*R);
}
return 0;
}

HZOI20190906模拟38 金,斯诺,赤的更多相关文章

  1. NOIP模拟测试38「金·斯诺·赤」

    金 辗转相减见祖宗 高精 #include<bits/stdc++.h> using namespace std; #define A 2000 #define P 1 #define N ...

  2. 湖南附中模拟day1 金坷垃

    题意描述"没有金坷垃,怎么种庄稼?"花花家有一块田,所有庄稼排成了 N 行 M 列.初始时,每棵庄稼都有一个自己的高度hi;j.花花每次可以使用 1mol 的金克拉使一棵庄稼的高度 ...

  3. Noip模拟38 2021.8.13

    T1 a 跟入阵曲很像,但是忘记入阵曲这题的思路是什么了 这里再提一下,入阵曲是子矩阵和是$k$的倍数,这道题目是子矩阵和是在一段区间内$[L,R]$ 因为这道题$n$特别小,$m$较大,考虑复杂度为 ...

  4. 2021.8.13考试总结[NOIP模拟38]

    T1 a 入阵曲.枚举矩形上下界,之后从左到右扫一遍.用树状数组维护前缀和加特判可以$A$,更保险要脸的做法是双指针扫,因为前缀和单调不减. $code:$ 1 #include<bits/st ...

  5. NOIP模拟 38

    liu_runda的题! 错过辽QAQ T1虽然没用题解的损益法,但是用高精%还能过.. 没想到敲完就过编译了,还以为要调一天呢 高精度的阴影没了- T2的思路很巧妙 首先一个区间最多有一种颜色占一半 ...

  6. [CSP-S模拟测试]:金(king)(高精度+模拟)

    题目传送门(内部题36) 输入格式 第一行一个整数$T$,表示数据组数. 接下来$T$行,每行两个空格隔开的整数$n,m$. 输出格式 对于每组数据,输出一行$"Yes"$或$&q ...

  7. HZOI20190906模拟39 工业,卡常,玄学

    题面:https://www.cnblogs.com/Juve/articles/11484209.html 工业: 推一个式子,AC 没有用组合数....推了2个多小时 我sbsbsbsbsbsbs ...

  8. NOIP 模拟 $38\; \rm c$

    题解 \(by\;zj\varphi\) 发现就是一棵树,但每条边都有多种不同的颜色,其实只需要保留随便三种颜色即可. 直接点分治,将询问离线,分成一端为重心,和两端都不为重心的情况. 每次只关心经过 ...

  9. NOIP 模拟 $38\; \rm b$

    题解 \(by\;zj\varphi\) 考虑转化问题,将计算最大公约数换为枚举最大公约数. 设 \(sum_i\) 为最大公约数为 \(i\) 的方案数,可以容斥求解,\(sum_i=f_i-\su ...

随机推荐

  1. LUOGU P2261 [CQOI2007]余数求和(数论分块)

    传送门 解题思路 数论分块,首先将 \(k\%a\) 变成 \(k-a*\left\lfloor\dfrac{k}{a}\right\rfloor\)形式,那么\(\sum\limits_{i=1}^ ...

  2. SQL 分组后获取每组中最大值

    场景:sql server 2008 drop table ID CREATE TABLE ID ( id ,) not null, code int , D date, PRIMARY KEY (i ...

  3. 《DSP using MATLAB》Problem 8.36

    上代码: function [wpLP, wsLP, alpha] = lp2lpfre(wplp, wslp) % Band-edge frequency conversion from lowpa ...

  4. 第九篇:Spring的applicationContext.xml配置总结

    在前面的一篇日志中,记录了web.xml配置启动的顺序,web启动到监听器ContextLoaderListener时,开始加载spring的配置文件applicationContext.xml(通常 ...

  5. Git合并时遇到冲突或错误后取消合并

    当合并分支时遇到错误或者冲突,分支旁边会多出“|MERGING”这个东西 有这个状态存在时,会导致后面想要再合并的时候提示如下 所以需要先取消这次合并,使用“git merge --abort”命令

  6. C# IP正则表达式

    public static bool IsValidIp(string strIn) { bool b = Regex.IsMatch(strIn, @"^[0-9]{1,3}\.[0-9] ...

  7. java_网络编程之BS(web案例)

    package BsServersocket; import java.io.*; import java.net.ServerSocket; import java.net.Socket; publ ...

  8. iOS开发系列-NSURLSession

    概述 NSURLSession是从iOS7开始出现的.NSURLSession比NSURLConnection简单很多并且避免了很多坑,因此目前公司项目大部分由NSURLConnection过度为NS ...

  9. SUMMARY | 二分查找

    package Search; public class biSearch { //标准的二分查找 public static int stdBiSearch(int[] array,int keyV ...

  10. LoadRunner参数化详解【转】

    距离上次使用loadrunner 已经有一年多的时间了.初做测试时在项目中用过,后面项目中用不到,自己把重点放在了工具之外的东西上,认为性能测试不仅仅是会用工具,最近又想有一把好的利器毕竟可以帮助自己 ...