Flappy Bird:
水题,直接维护飞到每个柱子时的最高最低高度,然后用最低高度算答案。
代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int Maxn=500010;
const int inf=2147483647;
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
int n,X;
struct Node{int x,a,b;}A[Maxn];
int main()
{
n=read(),X=read();
int high=0,low=0;A[0].x=0;
for(int i=1;i<=n;i++)
{
A[i].x=read(),A[i].a=read(),A[i].b=read();
int t1=high+(A[i].x-A[i-1].x),t2=low-(A[i].x-A[i-1].x);
if(A[i].a+1==A[i].b||t1<=A[i].a||t2>=A[i].b)return puts("NIE"),0;
high=min(A[i].b-1,t1),low=max(A[i].a+1,t2);
if(A[i].x&1)
{
if(!(high&1))high--;
if(!(low&1))low++;
}
if(!(A[i].x&1))
{
if(high&1)high--;
if(low&1)low++;
}
if(low>high)return puts("NIE"),0;
}
printf("%d",(low+A[n].x)/2);
}
Sabota?:
二分的话是非常水的题,不二分的话也不太难。注意到一定是某个子树的所有点一起叛变,所以直接树形DP, f [ x ] f[x] f[x]表示以 x x x为根子树全部叛变的最大比例即可。
代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int Maxn=500010;
const int inf=2147483647;
const double eps=1e-7;
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
int n,k,sz[Maxn];
vector<int>to[Maxn];
double f[Maxn];
void dfs(int x)
{
sz[x]=0;
if(!to[x].size()){sz[x]=f[x]=1;return;}
f[x]=0;
for(int i=0;i<to[x].size();i++)
{
int y=to[x][i];
dfs(y);
sz[x]+=sz[y];
}
for(int i=0;i<to[x].size();i++)
{
int y=to[x][i];
f[x]=max(f[x],min((double)sz[y]/sz[x],f[y]));
}
sz[x]++;
}
int main()
{
n=read();k=read();
for(int i=2;i<=n;i++)to[read()].push_back(i);
dfs(1);
double ans=0;
for(int i=1;i<=n;i++)
if(sz[i]>k&&ans<f[i])ans=f[i];
printf("%.10lf",ans);
}
Podzielno:
水题,显然的结论(由十进制联想一下就知道了嘛): B B B进制下的数,记 S ( x ) S(x) S(x)为 x x x的各位数字之和,则 x ≡ S ( x ) ( m o d    ( B − 1 ) ) x\equiv S(x)(\mod(B-1)) x≡S(x)(mod(B−1)),这个用归纳法证应该就好了吧,当位数为 1 1 1时,结论显然成立;当数位为 k k k时成立,数位为 k + 1 k+1 k+1也成立:设 x x x有 k k k位, y y y为一个 1 1 1位数, t = B x + y t=Bx+y t=Bx+y,则 t m o d    ( B − 1 ) = S ( x ) × B m o d    ( B − 1 ) + S ( y ) = S ( x ) + S ( y ) = S ( t ) t\mod(B-1)=S(x)\times B\mod (B-1)+S(y)=S(x)+S(y)=S(t) tmod(B−1)=S(x)×Bmod(B−1)+S(y)=S(x)+S(y)=S(t)。然后要尽量大,删一位就行了,询问二分一下。
代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int Maxn=1000010;
const int inf=2147483647;
LL read()
{
LL x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
int B,q,a[Maxn],s=0;LL sum[Maxn],w=0;
int main()
{
B=read(),q=read();
for(int i=0;i<B;i++)a[i]=read(),s=(s+(LL)a[i]*i%(B-1))%(B-1),w+=a[i];
if(s)a[s]--,w--;
sum[B]=0;
for(int i=B-1;i>=0;i--)sum[i]=sum[i+1]+a[i];
while(q--)
{
LL x=w-read();
if(x<=0)puts("-1");
else
{
int l=0,r=B-1;
while(l<=r)
{
int mid=l+r>>1;
if(sum[mid]>=x)l=mid+1;
else r=mid-1;
}
printf("%d\n",l-1);
}
}
}
Turysta:
Reprezentacje ró?nicowe:
这个题思考不够深入,没有做出来。只想到 l o g log log个数之后就会变得很大,做出贡献的一定是相邻的两个数,但是没有想到那些没有出现的差要怎么搞。其实数到了很大的时候,每次的 m e x mex mex也只会增加 1 1 1,用这个性质,二分一下还有几个数没有出现就可以了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int inf=2147483647;
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
map<int,bool>mp;
map<int,pair<int,int> >h;
int a[100],mex=1,n,b[2600],m=0;
int main()
{
a[1]=1,a[2]=2;
mp[1]=true;
for(int i=3;;i++)
{
if(i&1)a[i]=(a[i-1]<<1);
else
{
a[i]=a[i-1];
for(int j=mex+1;;j++)
if(!mp[j]){a[i]+=j;mex=j;break;}
}
for(int j=1;j<i;j++)mp[a[i]-a[j]]=true;
if(a[i]>1000000000&&!(i&1)){n=i;break;}
}
for(int i=2;i<=n;i++)
for(int j=1;j<i;j++)
if(!h.count(a[i]-a[j]))b[++m]=a[i]-a[j],h[a[i]-a[j]]=make_pair(i,j);
sort(b+1,b+1+m);
int T=read();
while(T--)
{
int x=read();
if(h.count(x))printf("%d %d\n",h[x].first,h[x].second);
else
{
int t=lower_bound(b+1,b+1+m,x)-b-1;
printf("%d %d\n",(x-t)*2+n,(x-t)*2+n-1);
}
}
}