1. 程式人生 > >POI2017

POI2017

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] 表示以 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 進位制下的數,記 S ( x ) S(x) x x 的各位數字之和,則 x S ( x ) ( m o d &ThinSpace;&ThinSpace; ( B 1 ) ) x\equiv S(x)(\mod(B-1)) ,這個用歸納法證應該就好了吧,當位數為 1 1 時,結論顯然成立;當數位為 k k 時成立,數位為 k + 1 k+1 也成立:設 x x k k 位, y y 為一個 1 1 位數, t = B x + y t=Bx+y ,則 t m o d &ThinSpace;&ThinSpace; ( B 1 ) = S ( x ) × B m o d &ThinSpace;&ThinSpace; ( 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) 。然後要儘量大,刪一位就行了,詢問二分一下。

程式碼:

#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 個數之後就會變得很大,做出貢獻的一定是相鄰的兩個數,但是沒有想到那些沒有出現的差要怎麼搞。其實數到了很大的時候,每次的 m e x mex 也只會增加 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
            
           

相關推薦

BZOJ4727 [POI2017]Turysta

spa cst n) printf ret ont int std print 這題太神了還是去看刺兒神題解吧。 http://www.cnblogs.com/neighthorn/p/6538364.html #include <cstdio> #inclu

BZOJ.4727.[POI2017]Turysta(哈密頓路徑/回路 競賽圖)

() markdown def clas tps solution blog turn htm 題目鏈接 \(Description\) 給出一個n個點的有向圖,任意兩個點之間有且僅一條有向邊。對於每個點v,求出從v出發的一條經過點數最多,且沒有重復經過同一個點一次以上的簡

BZOJ4724: [POI2017]Podzielno

AC int #define lse lower div sum clu fine $n \leq 1e6$,$n$進制下的$0,1,...,n-1$每個數有$a_i$個,$1 \leq a_i \lq 1e6$。$q \leq 1e5$個詢問,每次問用這些數字拼成的$n-

BZOJ4725: [POI2017]Reprezentacje ró?nicowe

getchar lB inf getch opera algo image repr 註意 $n \leq 1e5$,$x \leq 1e9$。 1e9呵呵,暴力處理$a_n$的前幾項直到1e9。然後處理出差的數列,每次在這裏面找,找得到就回答,找不到,那有貢獻的只有$a

BZOJ 4726 [POI2017]Sabota?:樹形dp

能夠 如果 define lin 傳送門 ble span HP source 傳送門 題意 某個公司有 $ n $ 個人,上下級關系構成了一個有根樹。其中有個人是叛徒(這個人不知道是誰)。對於一個人, 如果他下屬(直接或者間接, 不包括他自己)中叛徒占的比例超過 $ x

BZOJ4727 [POI2017]Turysta 【競賽圖哈密頓路徑/回路】

指向 air const 排序 space con res tps 維護 題目鏈接 BZOJ4727 題解 前置芝士 1.競賽圖存在哈密頓路徑 2.競賽圖存在哈密頓回路,當且僅當它是強聯通的 所以我們將圖縮點後,拓撲排序後一定是一條鏈,且之前的塊內的點和之後塊內的點的邊

【樹形dp】bzoj4726: [POI2017]Sabota?

成了 data end 其中 getch EDA dig 包括 由於 找點概率期望的題做一做 Description 某個公司有n個人, 上下級關系構成了一個有根樹。其中有個人是叛徒(這個人不知道是誰)。對於一個人, 如果他 下屬(直接或者間接, 不包括他

POI2017

Flappy Bird: 水題,直接維護飛到每個柱子時的最高最低高度,然後用最低高度算答案。 程式碼: #include<bits/stdc++.h> using namespace std; #define LL long long const int Maxn

4727: [POI2017]Turysta 競賽圖相關

題解: 這題算是競賽圖相關知識的簡單運用了吧。 完成此題,你需要知道: 1、競賽圖都存在一條哈密頓路徑。 這個比較簡單,反證法,假如沒有,設一條最長路徑為 a

bzoj 4726 [POI2017]Sabota?

題意 題解 嗯…好像這道題有O(N) 做法,所以下面的O(NlogN)卡常也就不足為奇了 直觀的想法肯定是二分 但是這道題並不需要,因為我們是能夠直接計算出來的 首先明確三個事:大於X和大於等於X是等效的;所謂的最壞情況,一定是葉子是叛徒;往上的一條鏈必須都是全部叛變(換言之,