男人八題2019


打的第三年男人八題了= = 感覺自己可能能創造一個EZ歷史上打過最多男人八題的人(嚶嚶嚶我明明是妹子啊

考場上是5題 目前補了7題

 

Biology

模擬= =

//Love and Freedom.
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define inf 20021225
using namespace std;
int read()
{
    int s=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return f*s;
}
int main()
{
    int k=read(); int ans=0,n=0;
    while(++n && k)
    {
        ans++; k--; if(!k) break;
        if(n!=1)
            ans+=n, k--;
    }
    printf("%d\n",ans);
    return 0;
}
biology

 

Chemistry

發現最有用的是中間的 它在每一個小矩形都算了 所以它對矩形之間的差是沒有貢獻的 然后考慮我們把兩個矩形補齊 所以就是看最小的和和最大的和然后直接乘一下就可以了

//Love and Freedom.
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define inf 20021225
using namespace std;
int read()
{
    int s=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return f*s;
}
int main()
{
    //freopen("chemistry.in","r",stdin);
    //freopen("chemistry.out","w",stdout);
    int n=read(),a=read(),b=read(),c=read(),d=read();
    int s1=a+b,s2=a+c,s3=b+d,s4=c+d;
    int mn=min(s1,min(s2,min(s3,s4))),mx=max(s1,max(s2,max(s3,s4)));
    int k=mx-mn; k=n-k; printf("%I64d\n",1ll*k*n);
    return 0;
}
chemistry

 

Chinese

考慮dp $f[i][j]=\sum_{k=0}^{i-1} f[i-1][j-k]$ 顯然前綴和優化 O(nk)

//Love and Freedom.
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define inf 20021225
#define mdn 998244353
#define N 1001
using namespace std;
int read()
{
    int s=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return f*s;
}
void upd(int &x,int y){x+=x+y>=mdn?y-mdn:y;}
int f[N],pre[N];
int qry(int l,int r)
{
    if(l<=0)    return pre[r];
    return (mdn+pre[r]-pre[l-1])%mdn;
}
int main()
{
    int n=read(),k=read();
    f[0]=pre[0]=1;
    for(int i=1;i<=n;i++)
    {
        int top=min(1ll*k,1ll*i*(i-1)/2);
        for(int j=1;j<=top;j++)    pre[j]=pre[j-1],upd(pre[j],f[j]);
        for(int j=0;j<=top;j++)    f[j]=qry(j-i+1,j);
    }
    printf("%d\n",f[k]);
    return 0;
}
chinese

 

English

其實之前看過但是考場上死活想不起來怎么做= = 二分答案然后考慮怎么判斷 中位數常見套路<x記為0 >=x記為1 然后發現最靠近mid的連續兩個0/1就是答案 特判01交替 多的最后會留下來 復雜度O(nlgn)

//Love and Freedom.
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
#define ll long long
#define inf 20021225
#define N 100010
using namespace std;
int read()
{
    int s=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')    f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return f*s;
}
int a[N<<1],tmp[N<<1],n;
bool check(int x)
{
    for(int i=1;i<(n<<1);i++)    tmp[i]=a[i]>=x;
    int mid=n;
    for(int d=0;d<n-1;d++)
    {
        if(tmp[mid-d-1]==tmp[mid-d])    return tmp[mid-d];
        if(tmp[mid+d+1]==tmp[mid+d])    return tmp[mid+d];
    }
    return tmp[1];
}
int main()
{
    n=read(); int mx=1;
    for(int i=1;i<(n<<1);i++)    a[i]=read(),mx=max(mx,a[i]);
    int l=1,r=mx,ans=1;
    while(l<=r)
    {
        int mid=l+r>>1;
        if(check(mid))    l=mid+1,ans=mid;
        else    r=mid-1;
    }
    printf("%d\n",ans);
    return 0;
}
english

 

Geography

2017男人八題原題海星 直接反過來做然后線段樹/bit維護就行

//Love and Freedom.
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define inf 20021225
#define N 100010
#define lowbit(x) (x&-x)
using namespace std;
int read()
{
    int s=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return f*s;
}
struct bit
{
    int a[N],n;
    void add(int x){while(x<=n)    a[x]++,x+=lowbit(x);}
    int qry(int x){int ans=0; while(x)    ans+=a[x],x-=lowbit(x); return ans;}
}t[2];
int cnt;
void modify(int l,int r)
{
    t[0].add(l); t[1].add(r); cnt++;
}
int query(int l,int r)
{
    int ans1=t[0].qry(r); ans1=cnt-ans1;
    int ans2=t[1].qry(l-1);
    return cnt-ans1-ans2;
}
int main()
{
    int n=read(); t[0].n=t[1].n=n;
    while(n--)
    {
        int t=read(),l=read(),r=read();
        if(t==1)    modify(l,r);
        else    printf("%d\n",query(l,r));
    }
    return 0;
}
geography

 

History

考慮直接暴力維護前k小值 然后呢有一個指針指向當前k個里面的最大的記為x 然后選進來一個看它>x的話直接選走 不然的話就選走x把它扔進來 然后發現這玩意是單調的所以它只會減O(n)次 那么我們就做完了

//Love and Freedom.
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define inf 20021225
#define N 100010
using namespace std;
int read()
{
    int s=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return f*s;
}
int a[N],buc[N],n,k,p,tmp[N]; ll val[2];
int main()
{
    n=read();
    for(int i=1;i<=n;i++)    a[i]=read();
    sort(tmp+1,tmp+n+1); k=read();
    while(k--)
    {
        p=read(); int k=1,top=0; val[0]=val[1]=0;
        for(int i=1;i<p;i++)    buc[a[i]]++,top=max(top,a[i]);
        for(int i=p;i<=n;i++)
        {
            if(a[i]>top)    val[k]+=a[i], k^=1;
            else
            {
                val[k]+=top; buc[top]--; k^=1; buc[a[i]]++;
                while(!buc[top] && top)    top--;
            }
        }
        for(;top;top--)
            while(buc[top])    val[k]+=top,k^=1,buc[top]--;
        printf("%lld\n",val[1]-val[0]);
    }
    return 0;
}
history

 

Math

留坑

 

Physics

好題ovo 做過弱化版 是正睿17的給 有一個N^2神仙DP方法之前會現在不會了反正對加強版不重要我們就不管了

考慮暴力DP $f[i][j]$表示左走不超過i一共j個葉子 $f[i][j]= [j==1] + \sum_{k=0}^j f[i-1][k] * f[i][j-k]$ 典型的卷積形式 根據常見套路 我們把它寫作生成函數形式$F_i(x)$

有$F_i(x)=x+F_i(x)*F_{i-1}(x)$ 所以有$F_i(x)=\frac{x}{1-F_{i-1}(x)}$ 繼續根據常見套路 可以把$F_i(x)$寫作$\frac{A_i(x)}{B_i(x)}$ 然后我們發現這個式子性質很好 把$F_{i-1}(x)$用這玩意替換一下可以得到遞推關系

$A_i(x)=xB_{i-1}(x)$ $B_i(x)=B_{i-1}(x)-A_{i-1}(x)$ 這個玩意顯然可以用矩乘優化轉移 具體形式懶得寫了可以看代碼 有邊界$A_0(x)=x$,$B_0(x)=1$ 還是常見套路 我們把單位根帶進去 然后IDFT一下就可以分別得到A和B接着多項式求逆一下就做完了qwq

代碼也不長很好寫。

//Love and Freedom.
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define inf 20021225
#define mdn 998244353
#define N 400010
#define G 3
using namespace std;
int read()
{
    int s=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    return f*s;
}
void upd(int &x,int y){x+=x+y>=mdn?y-mdn:y;}
struct mtx
{
    int a[2][2],n;
    mtx(){memset(a,0,sizeof(a)); n=2;}
    void diag(){memset(a,0,sizeof(a)); for(int i=0;i<n;i++) a[i][i]=1;}
};
mtx operator*(mtx a,mtx b)
{
    mtx tmp=mtx();
    for(int i=0;i<a.n;i++)    for(int j=0;j<a.n;j++)
        for(int k=0;k<a.n;k++)    upd(tmp.a[i][j],1ll*a.a[i][k]*b.a[k][j]%mdn);
    return tmp;
}
mtx mksm(mtx bs,int mi)
{
    mtx ans=mtx(); ans.diag();
    while(mi)
    {
        if(mi&1)    ans=ans*bs;
        bs=bs*bs; mi>>=1;
    }
    return ans;
}
int ksm(int bs,int mi)
{
    int ans=1;
    while(mi)
    {
        if(mi&1)    ans=1ll*ans*bs%mdn;
        bs=1ll*bs*bs%mdn; mi>>=1;
    }
    return ans;
}
int r[N];
int init(int n)
{
    int l=0,lim=1;
    while(lim<n)    lim<<=1,l++;
    for(int i=0;i<lim;i++)
        r[i]=(r[i>>1]>>1)|((i&1)<<l-1);
    return lim;
}
void ntt(int *a,int lim,int f)
{
    for(int i=0;i<lim;i++)    if(r[i]>i)
        swap(a[r[i]],a[i]);
    for(int k=2,mid=1;k<=lim;k<<=1,mid<<=1)
    {
        int Wn=ksm(G,(mdn-1)/k); if(f)    Wn=ksm(Wn,mdn-2);
        for(int w=1,i=0;i<lim;i+=k,w=1)    for(int j=0;j<mid;j++,w=1ll*w*Wn%mdn)
        {
            int x=a[i+j],y=1ll*w*a[i+mid+j]%mdn;
            a[i+j]=(x+y)%mdn; a[i+mid+j]=(mdn+x-y)%mdn;
        }
    }
    if(f)    for(int inv=ksm(lim,mdn-2),i=0;i<lim;i++)
        a[i]=1ll*a[i]*inv%mdn;
}
int tmp[N];
void poly_inv(int *a,int *ans,int n)
{
    if(n==1){ans[0]=ksm(a[0],mdn-2); return;}
    int mid=n+1>>1; poly_inv(a,ans,mid);
    int lim=init(n<<1);
    for(int i=0;i<n;i++)    tmp[i]=a[i];
    for(int i=n;i<lim;i++)    tmp[i]=0;
    ntt(tmp,lim,0); ntt(ans,lim,0);
    for(int i=0;i<lim;i++)
        ans[i]=(2ll-1ll*tmp[i]*ans[i]%mdn+mdn)*ans[i]%mdn;
    ntt(ans,lim,1);
    for(int i=n;i<lim;i++)    ans[i]=0;
}
mtx solve(int w,int n)
{
    mtx k; k.n=2; k.a[0][0]=1; k.a[0][1]=mdn-1; k.a[1][0]=w; k.a[1][1]=0;
    k=mksm(k,n); mtx ans; ans.a[0][0]=(k.a[0][0]+1ll*w*k.a[0][1]%mdn)%mdn;
    ans.a[1][0]=(k.a[1][0]+1ll*w*k.a[1][1]%mdn)%mdn;
    return ans;
}
int a[N],b[N],f[N],ib[N];
int main()
{
    int n=read(),m=read(); int lim; mtx ans;
    lim=init(n+2); int Wn=ksm(G,(mdn-1)/lim);
    for(int i=0,w=1;i<lim;i++,w=1ll*w*Wn%mdn)
        ans=solve(w,n),a[i]=ans.a[1][0],b[i]=ans.a[0][0],printf("%d %d\n",a[i],b[i]);
    ntt(a,lim,1); ntt(b,lim,1); poly_inv(b,ib,m);
    lim=init(m+n+2); ntt(ib,lim,0); ntt(a,lim,0);
    for(int i=0;i<lim;i++)    f[i]=1ll*a[i]*ib[i]%mdn;
    ntt(f,lim,1); for(int i=1;i<=m;i++)    printf("%d\n",f[i]);
    return 0;
}
physics


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM