ABC327
A
略
B
题意:给一个数B,询问A^A=B的A为多少
思路:快速幂暴力即可
ll ksm(ll a,ll b){
ll res=1;
while(b){
if(b&1)res=res*a;
a=a*a;
b>>=1;
}
return res;
}
//
void solve(){
ll b;cin>>b;
rep(i,1,16){
// debug(ksm(i,i));
if(ksm(i,i)==b){
cout<<i<<endl;return;
}
}
cout<<-1<<endl;
}
C
题意:
给定一个九宫格,判断:
1.每行1~9都出现
2.每列1~9都出现
3.每个3x3格子1~9都出现
思路:
用set模拟
int g[10][10];
void solve(){
rep(i,1,9){
rep(j,1,9)cin>>g[i][j];
}
int ok=1;
rep(i,1,9){
set<int>st;
rep(j,1,9)st.insert(g[i][j]);
if(st.size()!=9)ok=0;
}
rep(i,1,9){
set<int>st;
rep(j,1,9)st.insert(g[j][i]);
if(st.size()!=9)ok=0;
}
for(int z=1;z<=3;z++){
for(int y=1;y<=3;y++){
set<int>st;
for(int i=1+(z-1)*3;i<=3+(z-1)*3;i++){
for(int j=1+(y-1)*3;j<=3+(y-1)*3;j++){
st.insert(g[i][j]);
}
}
if(st.size()!=9)ok=0;
}
}
if(ok)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
D
题意:
给定两个数组A和B,其中数字大小不超过N
对于一个N的01数组c,需要满足对于1<=i<=M,c[a[i]]!=c[b[i]]
询问是否能够构造出c数组
思路:
经典的二元关系
种类并查集,每次merge把相互的对立面拉到同一个集合里
如果一个数和它的对立面出现在同一个集合里,则不行
void solve(){
int n,m;cin>>n>>m;
rep(i,1,2*n)f[i]=i;
vector<int>a(m+1);
vector<int>b(m+1);
rep(i,1,m)cin>>a[i];
rep(i,1,m)cin>>b[i];
rep(i,1,m){
merge(a[i]+n,b[i]);
merge(a[i],b[i]+n);
}
rep(i,1,n){
if(find(i)==find(i+n)){
cout<<"No"<<endl;return;
}
}
cout<<"Yes"<<endl;
}
E
题意:
给定一个比赛rating数组,求按顺序参加能通过给定公式计算出的最大rating
思路:
像01背包的n方dp
首先要先确定k的大小
不妨设f[i][j]:从1枚举到第i个,一共需要拿j个
f[i][j]=max(f[i-1][j],f[i-1][j-1]x0.9+a[i])
根据公式预处理一下即可
double f[5001][5001];
const double c=0.9;
double di[5001],mu[5001];
void solve(){
int n;cin>>n;
vector<double>a(n+1);
di[1]=1;
mu[1]=1200;
rep(i,2,n){
di[i]=di[i-1]*c+1;
mu[i]=1200*1.0/sqrtl(i);
}
rep(i,1,n)cin>>a[i];
double mx=-1e9;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
f[i][j]=max(f[i-1][j],f[i-1][j-1]*c+a[i]);
mx=max(mx,f[i][j]/di[j]-mu[j]);
}
}
cout<<fixed<<setprecision(11)<<mx<<endl;
}
F
题意:
给定一个T,X数组,表示Ti时间会在Xi位置降下一个苹果
现在可以划分一个长度为W的区间,持续D。
求最多能拿多少个苹果
思路:
显然排序后,可以通过双指针或队列来维护时间
考虑在维护出的合法时间段之内,如何获得长度为W的最大子段和
不妨化区间为节点:即[1,W],[2,W+1],[3,W+2].....[2E5.W+2E5-1]为线段树的节点(编号为下标)
求长度为w的最大区间子段和,即求这些节点的最大值
对于某个数x入队时,它会对[x-w+1,x]最大值产生+1的影响
同样出队时,会产生-1的影响
用线段树懒标记和mx维护
struct node{
int l,r;
int mx;
int tag;
}tr[4*maxn];
void pushdown(int p){
if(tr[p].tag){
tr[ls].mx=tr[ls].mx+tr[p].tag;
tr[rs].mx=tr[rs].mx+tr[p].tag;
tr[ls].tag+=tr[p].tag;
tr[rs].tag+=tr[p].tag;
tr[p].tag=0;
}
}
void pushup(int p){
tr[p].mx=max(tr[ls].mx,tr[rs].mx);
}
void build(int p,int l,int r){
tr[p].l=l;tr[p].r=r;tr[p].tag=0;tr[p].mx=0;
if(l==r)return;
int mid=l+r>>1;
build(ls,l,mid);
build(rs,mid+1,r);
}
void change(int p,int l,int r,int x){
if(l<=tr[p].l&&tr[p].r<=r){
tr[p].tag+=x;
tr[p].mx+=x;
return;
}
pushdown(p);
int mid=tr[p].l+tr[p].r>>1;
if(l<=mid)change(ls,l,r,x);
if(r>mid)change(rs,l,r,x);
pushup(p);
}
int query(int p,int l,int r){
if(l<=tr[p].l&&tr[p].r<=r){
return tr[p].mx;
}
int mid=tr[p].l+tr[p].r>>1;
pushdown(p);
int res=0;
if(l<=mid)res=max(res,query(ls,l,r));
if(r>mid)res=max(res,query(rs,l,r));
return res;
}
void solve(){
int n,d,w;cin>>n>>d>>w;
vector<pii>a(n+1);
rep(i,1,n)cin>>a[i].fi>>a[i].se;
build(1,1,2e5+1);
sort(a.begin()+1,a.end());
queue<pii>q;
int ans=0;
rep(i,1,n){
while(q.size()&&abs(q.front().fi-a[i].fi)>=d){
int x=q.front().se;
//(x-w ,x]
change(1,max(1ll,x-w+1),x,-1);
q.pop();
}
int x=a[i].se;
change(1,max(1ll,x-w+1),x,1);
ans=max(ans,query(1,1,2e5));
q.push(a[i]);
}
cout<<ans<<endl;
}

浙公网安备 33010602011771号