1001 Static Query on Tree
题意:树上有A,B,C三个集合,求有多少个点在A某个点到C某个点的路径与A某个点到C某个点的路径的交上
把1到A集合中所有点的路径打上标记1,把1到B集合中所有点的路径打上标记2,把C集合所有点的子树打上标记3,答案就是三个标记都有的点的个数。然后就是用树剖线段树维护一下了,我维护了区间&和区间 | 然后查询时下放懒标记,&等于3return区间长度,| 不等于3return0,一开始只维护了区间&,T了,加上区间 | 就过了,不会算复杂度,可能复杂度是错的吧qaq,然后好像可以维护1,2,3,12,13,23,123的数量,这样查询就是O(1)了
比赛时没看到单向边,想了快一个小时没想法,浪费了好多时间,最后还是想到了做法,可惜太晚了来不及了,复杂的正解还没仔细看……
#include<iostream>
#include<vector>
#include<bitset>
using namespace std;
#define debug(x) cout<<#x<<" "<<(x)<<endl
#define lson (p<<1)
#define rson (p<<1|1)
const int maxn=2e5+10;
struct Tree
{
int maxx[3],minn[3],flg[3];
};
int n,m[3];
vector<int> edg[maxn];
int tot=0,fa[maxn],son[maxn],siz[maxn],top[maxn],dep[maxn],dfn[maxn],rnk[maxn];
Tree tree[maxn<<2];
int a[3][maxn];
void dfs1(int fr)
{
siz[fr]=1;
son[fr]=-1;
for(int to:edg[fr])
{
if(to==fa[fr])continue;
dep[to]=dep[fr]+1;
fa[to]=fr;
dfs1(to);
siz[fr]+=siz[to];
if(son[fr]==-1||siz[to]>siz[son[fr]])son[fr]=to;
}
}
void dfs2(int fr,int t)
{
top[fr]=t;
dfn[fr]=++tot;
rnk[tot]=fr;
if(son[fr]==-1)return;
dfs2(son[fr],t);
for(int to:edg[fr])
{
if(to==fa[fr]||to==son[fr])continue;
dfs2(to,to);
}
}
void pushup(int p)
{
for(int i=0;i<3;++i)
{
tree[p].maxx[i]=tree[lson].maxx[i]|tree[rson].maxx[i];
tree[p].minn[i]=tree[lson].minn[i]&tree[rson].minn[i];
}
}
void pushdown(int p)
{
for(int i=0;i<3;++i)
{
if(tree[p].flg[i]==0)continue;
tree[lson].minn[i]=tree[p].flg[i]-1;
tree[rson].minn[i]=tree[p].flg[i]-1;
tree[lson].maxx[i]=tree[p].flg[i]-1;
tree[rson].maxx[i]=tree[p].flg[i]-1;
tree[lson].flg[i]=tree[p].flg[i];
tree[rson].flg[i]=tree[p].flg[i];
tree[p].flg[i]=0;
}
}
void updata(int s,int t,int x,int y,int l=1,int r=n,int p=1)
{
if(s<=l&&r<=t)
{
tree[p].maxx[x]=y;
tree[p].minn[x]=y;
tree[p].flg[x]=y+1;
return;
}
if(tree[p].flg[0]||tree[p].flg[1]||tree[p].flg[2])pushdown(p);
int mid=(l+r)>>1;
if(s<=mid)updata(s,t,x,y,l,mid,lson);
if(mid<t)updata(s,t,x,y,mid+1,r,rson);
pushup(p);
}
int query(int l=1,int r=n,int p=1)
{
if(tree[p].minn[0]&&tree[p].minn[1]&&tree[p].minn[2])return r-l+1;
if(!tree[p].maxx[0]||!tree[p].maxx[1]||!tree[p].maxx[2])return 0;
if(l==r)return 0;
if(tree[p].flg[0]||tree[p].flg[1]||tree[p].flg[2])pushdown(p);
int mid=(l+r)>>1;
int res=0;
res+=query(l,mid,lson);
res+=query(mid+1,r,rson);
return res;
}
void up(int x,int y,int z,int zz)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
updata(dfn[top[x]],dfn[x],z,zz);
x=fa[top[x]];
}
if(dfn[x]<dfn[y])updata(dfn[x],dfn[y],z,zz);
else updata(dfn[y],dfn[x],z,zz);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int _;
cin>>_;
int it;
while(_--)
{
for(int i=0;i<(maxn<<2);++i)
for(int c=0;c<=2;++c)
tree[i].maxx[c]=tree[i].minn[c]=tree[i].flg[c]=0;
int q;
cin>>n>>q;
for(int i=1;i<=n;++i)
edg[i].clear();
for(int i=2;i<=n;++i)
{
cin>>it;
edg[i].push_back(it);
edg[it].push_back(i);
}
tot=0;dep[1]=1;dfs1(1);dfs2(1,1);
// for(int i=1;i<=n;++i)
// cout<<top[i]<<" ";cout<<endl;
while(q--)
{
cin>>m[0]>>m[1]>>m[2];
for(int c=0;c<=2;++c)
for(int i=1;i<=m[c];++i)
cin>>a[c][i];
for(int c=0;c<=1;++c)
for(int i=1;i<=m[c];++i)
up(1,a[c][i],c,1);
for(int i=1;i<=m[2];++i)
updata(dfn[a[2][i]],dfn[a[2][i]]+siz[a[2][i]]-1,2,1);
cout<<query()<<'\n';
for(int c=0;c<=1;++c)
for(int i=1;i<=m[c];++i)
up(1,a[c][i],c,0);
for(int i=1;i<=m[2];++i)
updata(dfn[a[2][i]],dfn[a[2][i]]+siz[a[2][i]]-1,2,0);
}
}
return 0;
}
1002 C++ to Python
题意:C++语句转化成py
签到题,只输出()-,数字
#include<iostream>
#include<string>
using namespace std;
string s;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int _;
cin>>_;
while(_--)
{
cin>>s;
for(char ch:s)
{
if(ch=='-'||ch==','||ch=='('||ch==')')cout<<ch;
if(isdigit(ch))cout<<ch;
}
cout<<'\n';
}
return 0;
}
1003 Copy
题意:1操作复制l-r区间加在l-r区间后面,2操作查询第x个是多少
一次复制相当于把下面所有>r的查询减去(r-l+1),又因为l,r,x都是小于n,而答案输出的又是异或和(异或两次等于0)所以可以用bitset是维护答案。也可以把区间分为块,每次操作只会增加三块,实现时存一下块的索引和块大小的前缀和
比赛时队友想到了分块再重构的办法,可惜都不会写,赛后去要了份代码学习了一下
bitset:
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<bitset>
using namespace std;
#define debug(x) cout<<#x<<" "<<(x)<<endl
#define debug2(x,y) cout<<#x<<endl;for(int i=1;i<=y;++i)cout<<x[i]<<" ";cout<<endl
#define mem(x,y) memset(x,y,sizeof(x));
#define int long long
#define double long double
const int inf=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9;
const double PI=acos(-1.0);
const int maxn=1e5+10;
struct Que
{
int flg,l,r;
};
int n;
int a[maxn];
bitset<maxn> res;
Que que[maxn];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// cout<<fixed<<setprecision(6);
int _;
cin>>_;
while(_--)
{
int q;
cin>>n>>q;
for(int i=1;i<=n;++i)
res[i]=0;
for(int i=1;i<=n;++i)
cin>>a[i];
for(int i=1;i<=q;++i)
{
cin>>que[i].flg>>que[i].l;
if(que[i].flg==1)cin>>que[i].r;
}
for(int i=q;i>=1;--i)
{
if(que[i].flg==1)
{
bitset<maxn> l=(~bitset<maxn>(0)>>(maxn-que[i].r-1))&res;
bitset<maxn> r=(~bitset<maxn>(0)<<(que[i].r+1))&res;
res=l^(r>>(que[i].r-que[i].l+1));
}
if(que[i].flg==2)
res[que[i].l]=res[que[i].l]^1;
}
int ans=0;
for(int i=1;i<=n;++i)
if(res[i])ans^=a[i];
cout<<ans<<'\n';
}
return 0;
}
分块:
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
#define debug(x) cout<<#x<<" "<<(x)<<endl
#define debug2(x,y) cout<<#x<<endl;for(int i=1;i<=y;++i)cout<<x[i]<<" ";cout<<endl
#define mem(x,y) memset(x,y,sizeof(x));
#define int long long
#define double long double
const int inf=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9;
const double PI=acos(-1.0);
const int maxn=2e6+10;
const int s=350;
int n;
int a[maxn];
vector<int> blk[maxn];
int sum[maxn],pos[maxn];
void solve()
{
int q;
cin>>n>>q;
for(int i=1;i<=n;++i)
cin>>a[i];
for(int i=1;i<=n;++i)
blk[i].clear();
for(int i=1;i<=n;++i)
{
blk[(i-1)/s+1].push_back(a[i]);
sum[(i-1)/s+1]=i;
}
int tot=(n-1)/s+1;
int num=tot;
for(int i=1;i<=tot;++i)
pos[i]=i;
int flg,l,r,x;
int ans=0;
while(q--)
{
cin>>flg;
if(flg==1)
{
cin>>l>>r;
int ll=lower_bound(sum+1,sum+num+1,l)-sum;
int rr=lower_bound(sum+1,sum+num+1,r)-sum;
l-=sum[ll-1];
r-=sum[rr-1];
if(ll==rr)
{
++tot;
blk[tot].clear();
for(int i=0;i<r;++i)
blk[tot].push_back(blk[pos[ll]][i]);
++tot;
blk[tot].clear();
for(int i=l-1;i<r;++i)
blk[tot].push_back(blk[pos[ll]][i]);
++tot;
blk[tot].clear();
for(int i=r;i<(int)blk[pos[ll]].size();++i)
blk[tot].push_back(blk[pos[ll]][i]);
vector<int> t;
t.push_back(tot-2);
t.push_back(tot-1);
t.push_back(tot);
for(int i=ll+1;i<=num;++i)
t.push_back(pos[i]);
for(int i=0;i<(int)t.size();++i)
{
pos[ll+i]=t[i];
sum[ll+i]=sum[ll+i-1]+blk[t[i]].size();
if(sum[ll+i]>=n)
{
num=ll+i;
break;
}
}
}
else
{
++tot;
blk[tot].clear();
for(int i=l-1;i<(int)blk[pos[ll]].size();++i)
blk[tot].push_back(blk[pos[ll]][i]);
++tot;
blk[tot].clear();
for(int i=0;i<r;++i)
blk[tot].push_back(blk[pos[rr]][i]);
++tot;
blk[tot].clear();
for(int i=r;i<(int)blk[pos[rr]].size();++i)
blk[tot].push_back(blk[pos[rr]][i]);
vector<int> t;
t.push_back(tot-1);
t.push_back(tot-2);
for(int i=ll+1;i<rr;++i)
t.push_back(pos[i]);
t.push_back(tot-1);
t.push_back(tot);
for(int i=rr+1;i<=num;++i)
t.push_back(pos[i]);
for(int i=0;i<(int)t.size();++i)
{
pos[rr+i]=t[i];
sum[rr+i]=sum[rr+i-1]+blk[t[i]].size();
if(sum[rr+i]>=n)
{
num=rr+i;
break;
}
}
}
}
else
{
cin>>x;
int t=lower_bound(sum+1,sum+num+1,x)-sum;
ans^=blk[pos[t]][x-sum[t-1]-1];
}
}
cout<<ans<<'\n';
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// cout<<fixed<<setprecision(6);
int _;
cin>>_;
while(_--)
{
solve();
}
return 0;
}
1004 Keychains
题面:三维的有个圆环,问是否相扣
可以求A环与B环所在的平面的交点,交点一个在B环外面,一个在B环里面就YES,这样等价于求A球于B平面交点,再等价于A球与(A平面与B平面的交线)的交点
比赛时没有继续想下去,直接开始算了,结果死于太多特判除零,赛后用向量做就好多了
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
#define double long double
const double eps=1e-9;
struct dot
{
double x,y,z;
dot(double xx=0,double yy=0,double zz=0):x(xx),y(yy),z(zz){}
};
inline void print(dot &a){cout<<a.x<<" "<<a.y<<" "<<a.z<<endl;}
inline dot operator+(const dot &a,const dot &b){return dot(a.x+b.x,a.y+b.y,a.z+b.z);}
inline dot operator-(const dot &a,const dot &b){return dot(a.x-b.x,a.y-b.y,a.z-b.z);}
inline double len(const dot &a){return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);}
inline double operator*(const dot &a,const dot &b){return a.x*b.x+a.y*b.y+a.z*b.z;}
inline dot operator*(const double &k,const dot &a){return dot(k*a.x,k*a.y,k*a.z);}
inline dot operator/(const dot &a,const double &k){return dot(a.x/k,a.y/k,a.z/k);}
inline dot operator^(const dot &a,const dot &b){return dot(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);}
inline dot unit(const dot &a){return a/len(a);}//单位向量
struct line
{
dot d,a,b;
line(dot dd,dot aa):d(unit(dd)),a(aa),b(aa+unit(dd)){}
};
struct cir
{
dot o;
double r;
cir(double x=0,double y=0,double z=0,double rr=0):o(dot(x,y,z)),r(rr){}
};
inline dot vert(const line &l,const dot &o)//垂足
{
return l.a+((o-l.a)*l.d)*l.d;
}
inline double calc(double x,double y){return sqrt(x*x-y*y);}
inline vector<dot> cross_line_cir(const cir &c,const line &l)
{
vector<dot> res;
dot x=vert(l,c.o);
double dd=len(x-c.o);
if(c.r<dd-eps)return res;
if(abs(c.r-dd)<eps)
{
res.push_back(x);
return res;
}
double dis=calc(c.r,dd);
res.push_back(x+dis*l.d);
res.push_back(x-dis*l.d);
return res;
}
inline dot intion(dot p1,dot d1,dot p2,dot d2)
{
dot e=d1^d2;
dot u=d1^e;
return p1+((p2-p1)*d2)/(u*d2)*u;
}
inline bool incir(const cir &c,const dot &o){return len(o-c.o)<c.r-eps;}
inline bool outcir(const cir &c,const dot &o){return len(o-c.o)>c.r+eps;}
cir c[3];
dot f[3];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int _;
cin>>_;
while(_--)
{
for(int i=1;i<=2;++i)
cin>>c[i].o.x>>c[i].o.y>>c[i].o.z>>f[i].x>>f[i].y>>f[i].z>>c[i].r;
line l(f[1]^f[2],intion(c[1].o,f[1],c[2].o,f[2]));
// print(l.a);
vector<dot> ans=cross_line_cir(c[1],l);
if(ans.size()<2)
{
cout<<"No\n";
continue;
}
// print(ans[0]);print(ans[1]);
//if((incir(c[2],ans[0])&&outcir(c[2],ans[1]))||(outcir(c[2],ans[0])&&incir(c[2],ans[1])))
if(incir(c[2],ans[0])^incir(c[2],ans[1]))
cout<<"Yes\n";
else cout<<"No\n";
}
return 0;
}
1007 Snatch Groceries
题意:区间相交时有多少个人
签到题,按左边界排个序即可,队友签的
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
long long n,T,ans,now;
struct node{
int l,r;
bool operator<(const node&a)const{
return l<a.l||(l==a.l&&r<a.r);
}
}a[500000];
signed main(){
cin>>T;
while(T--){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].l>>a[i].r;
}
sort(a+1,a+1+n);
ans=0;
now=a[1].r;
for(int i=2;i<=n;i++){
if(a[i].l<=now){
break;
}
now=a[i].r;
ans++;
if(i==n)ans++;
}
cout<<ans<<endl;
}
}
1009 ShuanQ
题意:Q是P的逆元,求模数,无解就栓Q
分解一下质因数即可
比赛因为自己的问题WA好几发,哎
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
using namespace std;
#define debug(x) cout<<#x<<" "<<(x)<<endl
#define debug2(x,y) cout<<#x<<endl;for(int i=1;i<=y;++i)cout<<x[i]<<" ";cout<<endl
#define mem(x,y) memset(x,y,sizeof(x));
#define int long long
#define double long double
const int inf=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9;
const double PI=acos(-1.0);
int p,q,x;
vector<int> d;
set<int> ans;
bool solve()
{
d.clear();ans.clear();
int n=p*q-1;
for(int i=2;i*i<=n;++i)
{
if(n%i==0)
{
d.push_back(i);
while(n%i==0)n/=i;
}
}
if(n>1)d.push_back(n);
for(int it:d)
{
if(it>p&&it>q&&it>x&&p*q%it==1)
ans.insert(x*q%it);
}
if(ans.size()==1)return 1;
else return 0;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// cout<<fixed<<setprecision(6);
int _;
cin>>_;
while(_--)
{
cin>>p>>q>>x;
if(solve())cout<<*ans.begin()<<'\n';
else cout<<"shuanQ\n";
}
return 0;
}
1011 DOS Card
题意:在l-r的区间里选四个数,组成两对,每次的答案是ai*ai-aj*aj(i<j),求最大
线段树维护一些信息,细节看代码
线段树永远想不到维护什么……
题解做法:
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define debug(x) cout<<#x<<" "<<(x)<<endl
#define debug2(x,y) cout<<#x<<endl;for(int i=1;i<=y;++i)cout<<x[i]<<" ";cout<<endl
#define mem(x,y) memset(x,y,sizeof(x));
#define int long long
#define double long double
#define lson (p<<1)
#define rson (p<<1|1)
const int inf=0x3f3f3f3f3f3f3f;
const double eps=1e-9;
const double PI=acos(-1.0);
const int maxn=2e5+10;
struct Node
{
int len;
int max1,max2,min1,min2,d1,d2,d1_min,d1_max;
void init()
{
max1=max2=d1=d2=d1_min=d1_max=-inf;
min1=min2=inf;
}
void up_max(int x)
{
if(x>max1)max2=max1,max1=x;
else if(x>max2)max2=x;
}
void up_min(int x)
{
if(x<min1)min2=min1,min1=x;
else if(x<min2)min2=x;
}
Node operator+(const Node &r)const
{
Node res;
res.len=len+r.len;
res.init();
res.up_max(max1);res.up_max(max2);
res.up_max(r.max1);res.up_max(r.max2);
res.up_min(min1);res.up_min(min2);
res.up_min(r.min1);res.up_min(r.min2);
res.d1=max({d1,r.d1,max1-r.min1});
res.d2=max({d2,r.d2,max1+max2-r.min1-r.min2,d1_max-r.min1,max1+r.d1_min,d1+r.d1});
res.d1_max=max({d1_max,r.d1_max,d1+r.max1,max1+r.d1});
res.d1_max=max(res.d1_max,max1+max2-r.min1);
res.d1_max=max(res.d1_max,max1+r.max1-r.min1);
res.d1_min=max({d1_min,r.d1_min,d1-r.min1,-min1+r.d1});
res.d1_min=max(res.d1_min,max1-r.min1-r.min2);
res.d1_min=max(res.d1_min,max1-min1-r.min1);
return res;
}
};
int n;
int a[maxn];
Node tree[maxn<<2];
void build(int l=1,int r=n,int p=1)
{
tree[p].init();
if(l==r)
{
tree[p].len=1;
tree[p].up_min(a[l]*a[l]);
tree[p].up_max(a[l]*a[l]);
return;
}
int mid=(l+r)>>1;
build(l,mid,lson);
build(mid+1,r,rson);
tree[p]=tree[lson]+tree[rson];
}
Node query(int s,int t,int l=1,int r=n,int p=1)
{
// cout<<l<<r<<" "<<p<<endl;
if(s<=l&&r<=t)return tree[p];
int mid=(l+r)>>1;
if(t<=mid)return query(s,t,l,mid,lson);
else if(mid<s)return query(s,t,mid+1,r,rson);
else
{
Node it=query(s,t,l,mid,lson)+query(s,t,mid+1,r,rson);
return it;
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// cout<<fixed<<setprecision(6);
int _;
cin>>_;
while(_--)
{
int q;
cin>>n>>q;
for(int i=1;i<=n;++i)
cin>>a[i];
build();
int l,r;
while(q--)
{
cin>>l>>r;
Node ans=query(l,r);
cout<<ans.d2<<'\n';
}
}
return 0;
}
神奇的变量名做法:
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define debug(x) cout<<#x<<" "<<(x)<<endl
#define debug2(x,y) cout<<#x<<endl;for(int i=1;i<=y;++i)cout<<x[i]<<" ";cout<<endl
#define mem(x,y) memset(x,y,sizeof(x));
#define int long long
#define double long double
#define lson (p<<1)
#define rson (p<<1|1)
const int inf=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9;
const double PI=acos(-1.0);
const int maxn=2e5+10;
struct Node
{
int d,x,xx,dd,dx,xd,dxd,xdx,ddx,dxx,dxdx,ddxx;
void init()
{
d=x=xx=dd=dx=xd=dxd=xdx=ddx=dxx=dxdx=ddxx=-inf;
}
Node operator+(const Node &r)const
{
Node res;
res.init();
res.d=max(d,r.d);
res.x=max(x,r.x);
res.xx=max({xx,r.xx,x+r.x});
res.dd=max({dd,r.dd,d+r.d});
res.xd=max({xd,r.xd,x+r.d});
res.dx=max({dx,r.dx,d+r.x});
res.ddx=max({ddx,r.ddx,dd+r.x,d+r.dx});
res.dxd=max({dxd,r.dxd,dx+r.d,d+r.xd});
res.dxx=max({dxx,r.dxx,d+r.xx,dx+r.x});
res.xdx=max({xdx,r.xdx,x+r.dx,xd+r.x});
res.ddxx=max({ddxx,r.ddxx,d+r.dxx,dd+r.xx,ddx+r.x});
res.dxdx=max({dxdx,r.dxdx,d+r.xdx,dx+r.dx,dxd+r.x});
return res;
}
};
int n;
int a[maxn];
Node tree[maxn<<2];
void build(int l=1,int r=n,int p=1)
{
tree[p].init();
if(l==r)
{
tree[p].x=-a[l]*a[l];
tree[p].d=a[l]*a[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,lson);
build(mid+1,r,rson);
tree[p]=tree[lson]+tree[rson];
}
Node query(int s,int t,int l=1,int r=n,int p=1)
{
if(s<=l&&r<=t)return tree[p];
int mid=(l+r)>>1;
if(t<=mid)return query(s,t,l,mid,lson);
else if(mid<s)return query(s,t,mid+1,r,rson);
else return query(s,t,l,mid,lson)+query(s,t,mid+1,r,rson);
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// cout<<fixed<<setprecision(6);
int _;
cin>>_;
while(_--)
{
int q;
cin>>n>>q;
for(int i=1;i<=n;++i)
cin>>a[i];
build();
int l,r;
while(q--)
{
cin>>l>>r;
Node ans=query(l,r);
cout<<max(ans.ddxx,ans.dxdx)<<endl;
}
}
return 0;
}
1012 Luxury cruise ship
题意:每天加7或31或365,正好存x最少需要多少天
bfs预处理到lca(7,31,365),一个轮回,答案是x/79205*(7*31)+ans[x%79205],好像也可以背包……
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define debug(x) cout<<#x<<" "<<(x)<<endl
#define debug2(x,y) cout<<#x<<endl;for(int i=1;i<=y;++i)cout<<x[i]<<" ";cout<<endl
#define mem(x,y) memset(x,y,sizeof(x));
#define int long long
#define double long double
const int inf=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9;
const double PI=acos(-1.0);
const int maxn=79205+10;
struct Node
{
int res,cnt;
};
int n;
bool vis[maxn];
int ans[maxn];
void init()
{
mem(vis,0);
mem(ans,-1);
queue<Node> q;
q.push({0,0});
while(!q.empty())
{
Node cur=q.front();
q.pop();
if(vis[cur.res])continue;
vis[cur.res]=1;
ans[cur.res]=cur.cnt;
if(cur.res+7<=79205)q.push({cur.res+7,cur.cnt+1});
if(cur.res+31<=79205)q.push({cur.res+31,cur.cnt+1});
if(cur.res+365<=79205)q.push({cur.res+365,cur.cnt+1});
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// cout<<fixed<<setprecision(6);
init();
int _;
cin>>_;
while(_--)
{
cin>>n;
if(ans[n%79205]!=-1)cout<<n/79205*(7*31)+ans[n%79205]<<'\n';
else cout<<-1<<'\n';
}
return 0;
}