小凯逛超市
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1000000007;
int f[405][405];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n,m,v;
cin>>n>>m>>v;
memset(f,0,sizeof(f));
f[0][0]=1;
for(int t=1;t<=n;t++)
{
int g;
cin>>g;
for(int i=1;i<=m;i++)
{
for(int j=g;j<=v;j++)
{
(f[i][j]+=f[i-1][j-g])%=mod;
}
}
}
cout<<accumulate(f[m]+1,f[m]+v+1,0ll)%mod<<endl;
}
return 0;
}
小凯在长跑
hypot:给定两点横纵坐标差,计算距离。例如:hypot(x,y)
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int d,r,x,y;
cin>>d>>r>>x>>y;
double ans;
if(abs(y)<=d)
{
ans=min(abs(x-r),abs(x+r));
}
else if(y>=d)
{
ans=abs(hypot(x,y-d)-r);
}
else if(y<=-d)
{
ans=abs(hypot(x,y+d)-r);
}
cout<<fixed<<setprecision(0)<<ans<<"\n";
}
return 0;
}
小凯做梦
- 考虑在树上的任意一次移动都会让所有原来距离为1的点的距离变成 0,所有原来距离为 0 的点的距离变成 1
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
vector<pii>a[500005];
int d[500005],cnt;
void dfs(int u,int fa)
{
cnt+=(d[u]>0);
for(auto [v,w]:a[u])
{
if(v!=fa)
{
d[v]=(d[u]+w)%2;
dfs(v,u);
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
a[i].clear();
}
for(int i=1;i<n;i++)
{
int u,v,w;
cin>>u>>v>>w;
w%=2;
a[u].push_back({v,w});
a[v].push_back({u,w});
}
d[1]=cnt=0;
dfs(1,0);
cout<<cnt*cnt*cnt+(n-cnt)*(n-cnt)*(n-cnt)<<"\n";
}
return 0;
}
小凯取石子
#include <bits/stdc++.h>
#define int long long
using namespace std;
const signed mod=998244353;
constexpr int power(int n,int p)
{
if(p==0)
{
return 1;
}
long long tmp=power(n,p/2);
if(p%2==1)
{
return tmp*tmp%mod*n%mod;
}
return tmp*tmp%mod;
}
constexpr signed inv2=power(2,mod-2);
int f(int x)
{
if(x<0)
{
return 1;
}
if(x==0)
{
return 0;
}
if(x%5==2)
{
x/=5;
x++;
return 1-power(inv2,x)+mod;
}
else if(x%5==0)
{
x/=5;
return 1-power(inv2,x)+mod;
}
else
{
return 1;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
cout<<inv2*(f(n-1)+f(n-4))%mod<<endl;
}
return 0;
}
小凯爱数学
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353;
typedef vector<vector<int> > matrix;
matrix operator *(matrix a,matrix b)
{
int n=a.size(),m=a[0].size(),k=b[0].size();
matrix res(n,vector<int>(k));
for(int i=0;i<n;i++)
{
for(int j=0;j<k;j++)
{
for(int l=0;l<m;l++)
{
(res[i][j]+=(a[i][l]*b[l][j]%mod))%=mod;
}
}
}
return res;
}
matrix E(int n)
{
matrix res(n,vector<int>(n));
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
res[i][j]=0;
}
res[i][i]=1;
}
return res;
}
matrix power(matrix n,int p)
{
if(p==0)
{
return E(n.size());
}
matrix tmp=power(n,p/2);
if(p%2==1)
{
return tmp*tmp*n;
}
return tmp*tmp;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n,m;
cin>>n>>m;
if(n<m)
{
vector<int>f(m);
vector<int>g(m);
f[0]=1;
for(int i=1;i<=n;i++)
{
g=f;
for(int j=0;j<m;j++)
{
(f[j]+=g[(j-i%m+m)%m])%=mod;
}
}
cout<<(f[0]-1+mod)%mod<<"\n";
}
else
{
matrix f(m,vector<int>(1));
matrix g(m,vector<int>(1));
f[0][0]=2;
for(int i=1;i<m;i++)
{
g=f;
for(int j=0;j<m;j++)
{
(f[j][0]+=g[(j-i+m)%m][0])%=mod;
}
}
vector<vector<int> >a(m,vector<int>(m));
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
a[i][j]=f[(i-j+m)%m][0];
}
}
f=power(a,n/m-1)*f;
for(int i=1;i<=n%m;i++)
{
g=f;
for(int j=0;j<m;j++)
{
(f[j][0]+=g[(j-i+m)%m][0])%=mod;
}
}
cout<<(f[0][0]-1+mod)%mod<<"\n";
}
}
return 0;
}
- 也可以用循环卷积加速单次合并
- 可以使用resize函数改变vector的大小,自动补齐0
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef vector<int> poly;
const int mod=998244353;
int n,m;
poly E(int n)
{
poly res(n);
res[0]=1;
return res;
}
int rev[5000005],p[5000005][2];
int power(int n,int p)
{
if(p==0)
{
return 1;
}
long long tmp=power(n,p/2);
if(p%2==1)
{
return tmp*tmp%mod*n%mod;
}
return tmp*tmp%mod;
}
void NTT(poly &f,int opt)
{
int n=f.size();
for(int i=1;i<n;i++)
{
if(i<rev[i])
{
swap(f[i],f[rev[i]]);
}
}
for(int m=2;m<=n;m*=2)
{
int k=m/2;
for(int i=0;i<n;i+=m)
{
long long cur=1,step;
if(opt==1)
{
step=p[m][0];
}
else
{
step=p[m][1];
}
for(int j=0;j<k;j++)
{
long long tmp=cur*f[i+j+k]%mod;
f[i+j+k]=(f[i+j]-tmp)%mod;
f[i+j]=(f[i+j]+tmp)%mod;
cur=cur*step%mod;
}
}
}
}
poly operator*(poly a,poly b)
{
poly c(a.size()+b.size()-1);
int p=0;
while((1<<p)<c.size())
{
p++;
}
for(int i=1;i<(1<<p);i++)
{
rev[i]=(rev[i>>1]>>1);
if(i&1)
{
rev[i]+=(1<<(p-1));
}
}
c.resize(1<<p);
a.resize(c.size());
b.resize(c.size());
NTT(a,1),NTT(b,1);
for(int i=0;i<c.size();i++)
{
c[i]=a[i]*b[i]%mod;
}
NTT(c,-1);
p=power(c.size(),998244351);
for(int i=0;i<c.size();i++)
{
c[i]=c[i]*p%mod;
}
for(int i=0;i+m<c.size();i++)
{
c[i]=(c[i]+c[i+m])%mod;
}
c.resize(m);
return c;
}
void pre()
{
for(int i=1;i<=22;i++)
{
p[1<<i][0]=power(3,998244352/(1<<i));
p[1<<i][1]=power(3,998244352-998244352/(1<<i));
}
}
poly power(poly n,int p)
{
if(p==0)
{
return E(n.size());
}
poly tmp=power(n,p/2);
if(p%2==1)
{
return tmp*tmp*n;
}
return tmp*tmp;
}
ostream& operator <<(ostream& os,poly x)
{
for(int i:x)
{
os<<i;
os<<' ';
}
return os;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
pre();
int T;
cin>>T;
while(T--)
{
cin>>n>>m;
if(n<m)
{
poly f(m);
poly g(m);
f[0]=1;
for(int i=1;i<=n;i++)
{
g=f;
for(int j=0;j<m;j++)
{
(f[j]+=g[(j-i%m+m)%m])%=mod;
}
}
cout<<(f[0]-1+mod)%mod<<"\n";
}
else
{
poly f(m);
poly g(m);
f[0]=2;
for(int i=1;i<m;i++)
{
g=f;
for(int j=0;j<m;j++)
{
(f[j]+=g[(j-i+m)%m])%=mod;
}
}
f=f*power(f,n/m-1);
for(int i=1;i<=n%m;i++)
{
g=f;
for(int j=0;j<m;j++)
{
(f[j]+=g[(j-i+m)%m])%=mod;
}
}
cout<<(f[0]-1+mod)%mod<<"\n";
}
}
return 0;
}
小凯用git
- 如果你要自定义构造函数,但在定义数组的时候又不想给出具体的值,那就要给构造函数的参数提供默认值
- 大概是因为getline会把数字后的回车也读进去,所以要多循环一次
#include <bits/stdc++.h>
#define int long long
using namespace std;
vector<int>a[5005];
struct Branch
{
string name;
int node;
bool life;
Branch(string name="",int node=0)
{
this->name=name;
this->node=node;
this->life=true;
}
}b[5005];
bool cmp(Branch a,Branch b)
{
return a.name<b.name;
}
bool pd(int p,int q)
{
if(p==q)
{
return true;
}
bool f=false;
for(int fa:a[q])
{
f|=pd(p,fa);
}
return f;
}
int cntn,cntb,delb,head;
void output()
{
cout<<cntb-delb<<"\n";
for(int i=1;i<=cntb;i++)
{
if(b[i].life)
{
cout<<b[i].name<<" "<<b[i].node<<"\n";
}
}
cout<<cntn<<"\n";
for(int i=1;i<=cntn;i++)
{
cout<<a[i].size();
sort(a[i].begin(),a[i].end());
for(int fa:a[i])
{
cout<<" "<<fa;
}
cout<<"\n";
a[i].clear();
}
fflush(stdout);
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
head=cntb=cntn=1;
delb=0;
b[1]=Branch("main",1);
int n;
cin>>n;
for(int t=0;t<=n;t++)
{
string s;
getline(cin,s);
if(s=="commit")
{
cntn++;
a[cntn].push_back(b[head].node);
b[head].node=cntn;
}
else if(s.substr(0,5)=="reset")
{
int p=0;
for(int i=5;i<s.size();i++)
{
if(isdigit(s[i]))
{
p=p*10+s[i]-'0';
}
}
if(p>0)
{
b[head].node=p;
}
}
else if(s.substr(0,5)=="merge")
{
s.erase(0,6);
int p=-1;
for(int i=1;i<=cntb;i++)
{
if(b[i].name==s)
{
p=i;
break;
}
}
if(!pd(b[p].node,b[head].node)&&!pd(b[head].node,b[p].node))
{
cntn++;
a[cntn].push_back(b[p].node);
a[cntn].push_back(b[head].node);
b[head].node=cntn;
}
else if(pd(b[head].node,b[p].node))
{
b[head].node=b[p].node;
}
}
else if(s.substr(0,6)=="branch")
{
s.erase(0,7);
if(s[0]=='-')
{
s.erase(0,3);
for(int i=1;i<=cntb;i++)
{
if(b[i].life&&b[i].name==s)
{
b[i].life=false;
delb++;
break;
}
}
}
else
{
int p=b[head].node;
if(s.find(' ')!=-1)
{
for(int i=s.find(' ');i<s.size();i++)
{
if(isdigit(s[i]))
{
p=p*10+s[i]-'0';
}
}
}
string name="";
for(int i=0;i<s.size()&&s[i]!=' ';i++)
{
name+=s[i];
}
bool f=false;
for(int i=1;i<=cntb;i++)
{
if(b[i].life&&b[i].name==name)
{
f=true;
break;
}
}
if(f==false)
{
cntb++;
b[cntb]=Branch(name,p);
}
}
}
else if(s.substr(0,8)=="checkout")
{
s.erase(0,9);
for(int i=1;i<=cntb;i++)
{
if(b[i].life&&b[i].name==s)
{
head=i;
break;
}
}
}
}
sort(b+1,b+cntb+1,cmp);
output();
}
return 0;
}
小凯想要MVP!
- 考虑让两个子序列相交不影响长度和元素和相同,因此忽略掉这条限制,由此解除了两个子序列之间的纠缠
- 然后观察到任意两个这样的子序列都可以等价为两个长度为\(\lfloor \frac{n}{2} \rfloor\)的序列,根据抽屉原理,只要\(\binom{n}{\lfloor \frac{n}{2} \rfloor}> m\cdot \lfloor \frac{n}{2} \rfloor\)就一定有解
- 考虑到\(3^6=729\),\(3^{18}\)的时间复杂度差不多就接近程序的极限了
#include <bits/stdc++.h>
#define int long long
using namespace std;
int c[200005],s[1<<23];
unordered_map<int,bool>q;
int lowbit(int n)
{
return n&(-n);
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n,m;
cin>>n>>m;
bool f=false;
for(int i=0;i<n;i++)
{
cin>>c[i];
}
if(n<24)
{
for(int m=1;m<=n;m++)
{
q.clear();
for(int j=(1<<m)-1,t;j<(1<<n);t=j+lowbit(j),j=t|(((lowbit(t)/lowbit(j))>>1)-1))
{
int p=__builtin_ctz(j);
s[j]=s[j-(1<<p)]+c[p];
if(q.find(s[j])!=q.end())
{
f=true;
break;
}
q[s[j]]=true;
}
}
}
else
{
f=true;
}
f==true?cout<<"YES\n":cout<<"NO\n";
}
return 0;
}