大体状况
150/300
T1 uria
题目大意
求
a+b≤n
且
a+b|ab
的
(a,b)
对数。
n≤1014
分析
令
Gcd(a,b)=d
,然后设
a′=a/d,b′=b/d
原条件可转换为
(a′+b′)d|a′b′d2
然后
(a′+b′)|d
,又
(a′+b′)d≤n
所以
(a′+b′)≤n√
枚举
(a′+b′)=k
,那么满足条件的d有
nk2
个
然后
(a′+b′)
有
φ(k)
对,
用线性筛然后累计答案。
代码
这种数学题怎么写得出来啊
#include<bits/stdc++.h>
using namespace std;
#define Komachi is retarded
#define REP(i,a,b) for(register int i=(a),i##_end_=(b);i<i##_end_;i++)
#define M 10000004
#define LL long long
int Phi[M],Pri[M>>1],pt;
bool Mark[M];
LL n,Ans;
int main(){
scanf("%lld",&n);
REP(i,2,M){
if(!Mark[i])Pri[pt++]=i,Phi[i]=i-1;
REP(j,0,pt){
LL pos=1ll*i*Pri[j];
if(pos>=M)break;
Mark[pos]=1;
if(!(i%Pri[j])){Phi[pos]=Phi[i]*Pri[j];break;}
Phi[pos]=Phi[i]*(Pri[j]-1);
}
Ans+=n/i/i*Phi[i];
}
printf("%lld",Ans);
return 0;
}
T2 hamon
题目大意
求LIS及其方案数
分析
正常的DP及数据结构维护
代码
然后就因为各种原因写炸了
#include<bits/stdc++.h>
using namespace std;
#define Komachi is retarded
#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)
#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;i--)
#define chkmin(a,b) a=min(a,b)
#define chkmax(a,b) a=max(a,b)
#define Mod 123456789
#define Add(a,b) ((a+=b)%=Mod)
#define LL long long
#define M 100004
int n,type;
inline void chk(int &Mx,int &Sum,const int &t,const int &s){
if(t>Mx) Mx=t,Sum=s;
else if(t==Mx) Add(Sum,s);
}
struct BIT{
int Mx[M],Sum[M];
void Updata(int a,int t,int s){
while(a<M) chk(Mx[a],Sum[a],t,s),a+=a&-a;
}
void Query(int a,int &t,int &s){
t=s=0;
while(a) chk(t,s,Mx[a],Sum[a]),a^=a&-a;
}
}Bit;
int A[M];
void Solve(){
int t,s;
REP(i,0,n) Bit.Query(A[i]-1,t,s),Bit.Updata(A[i],t+1,t?s:1);
Bit.Query(M-1,t,s);
printf("%d\n",t);
if(type)printf("%d\n",s);
}
int main(){
scanf("%d%d",&n,&type);
REP(i,0,n)scanf("%d",&A[i]);
Solve();
return 0;
}
T3 reviel
分析
P40
暴力瞎搞
P80
弄个斐波那契数列求出每层黑点白点数
然后瞎写凑答案
P100
把P80优化一下即可
然后应该有正常一些的写法
我是直接枚举lca然后前缀和求的
代码
似乎被卡常
#include<bits/stdc++.h>
using namespace std;
#define Komachi is retarded
#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)
#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;i--)
#define chkmin(a,b) a=min(a,b)
#define chkmax(a,b) a=max(a,b)
#define LL long long
#define Mod 123456789
#define Add(a,b) ((a+=b)%=Mod)
int n;
struct P100{
static const int M=5004;
int W[M],B[M],Num[M][M<<1],Ans[M<<1];
void Solve(){
W[0]=1;
REP(i,1,n+4){
W[i]=B[i-1];
B[i]=(B[i-1]+W[i-1])%Mod;
}
REP(j,1,n) REP(k,2,n)
Add(Num[max(j,k)][j+k],1ll*W[j-1]*W[k]%Mod);
REP(i,1,n) REP(j,1,2*n+1) Add(Num[i][j],Num[i-1][j]);
REP(i,0,n){
int Val=W[i];
REP(j,i+2,n)
Add(Ans[j-i],1ll*Val*W[j-i]%Mod);
Val=B[i];
REP(j,1,2*n+1)
Add(Ans[j],1ll*Val*Num[n-i-1][j]%Mod);
}
REP(i,1,2*n+1) printf("%d%c",Ans[i]," \n"[i==2*n]);
}
}P100;
int main(){
scanf("%d",&n);
P100.Solve();
return 0;
}
总结
T1完全不会写。
T2写太快没有检查。
T3被成功卡常。
然后就这样了。
考得十分爆炸。
我还是太水啦。