1005 csp-s 60 涼涼

T1 嘟嘟嚕node

上來一看數據範圍1e9就矇蔽,而後不知所措的打了一個 $ O(n)$的無腦算法,因爲本人真的腦小,致使O(n)的柿子推了好長時間,致使心態崩了,而後........ 今天能明白了log的算法,算是約瑟夫問題弄明白了,沒有想到跳躍式的居然能夠log求。c++

#include<bits/stdc++.h>
using namespace std;
#define re register
inline int read()
{
    int x=0,f=1;char cc=getchar();
    while(cc>'9'||cc<'0'){if(cc=='-')f=-1;cc=getchar();}
    while(cc>='0'&&cc<='9'){x=(x<<1)+(x<<3)+cc-'0';cc=getchar();}
    return x*f;
}
const int maxn=5000005;
int n,k,m,S;
int ans[maxn];
queue<int>q;
set<int>pc,fc;
stack<int>s;
int main()
{
    n=read(),k=read(),m=read(),S=read();
    for(int i=1,u;i<=m;i++)
    {
        u=read();
        ans[u]=-1;
    }
    q.push(S);
    for(re int i=1;i<=n;++i)
        if(i!=S&&ans[i]!=-1)
        {
            if(i&1)pc.insert(i);
            else fc.insert(i);
        }
    while(q.size()&&(!pc.empty()||!fc.empty()))
    {
        int x=q.front();q.pop();
        if((x&1)==(k&1))
        {
            for(auto it=pc.lower_bound(max(x-k+1,k-x));it!=pc.end()&&*it<x+k;++it)
            {
                int zz=(k-(abs(x-*it)+1))>>1;
                if(zz>n-max(*it,x))break;
                q.push(*it);
                ans[*it]=ans[x]+1;
                s.push(*it);
            }
            while(s.size())pc.erase(s.top()),s.pop();
            continue;
        }
        for(auto it=fc.lower_bound(max(x-k+1,k-x));it!=fc.end()&&*it<x+k;++it)
        {
            int zz=(k-(abs(x-*it)+1))>>1;
            if(zz>n-max(*it,x))break;
            ans[*it]=ans[x]+1;
            q.push(*it);
            s.push(*it);
        }
        while(s.size())fc.erase(s.top()),s.pop();
    }
    for(re int i=1;i<=n;++i)
    {
        if(!ans[i]&&(i!=S))ans[i]=-1;
        printf("%d ",ans[i]);
    }
    return 0;
}
View Code

T2 天才紳士少女助手克里斯蒂娜算法

看題就發現是原題,而後想到當時本身連題解都沒有頹,就崩了,而後想到當時就是wba大神造的數據,我就感到了一絲不妙,其實就是拆一下柿子就出來了!ide

 

 

 

而後我就懷着爆零的心情去看T3spa

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read()
{
    int f=1,x=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int maxn=5000005;
const int mod=20170927;
int n,m;
struct BIT
{
    int tr[maxn];
    inline int lowbit(int x){return x&(-x);}
    inline int query(int x)
    {
        int res=0;
        while(x)
        {
            (res+=tr[x]+mod)%=mod;
            x-=lowbit(x);
        }
        return res;
    }
    inline void update(int x,int val)
    {
        while(x<=n)
        {
            (tr[x]+=val+mod)%=mod;
            x+=lowbit(x);
        }
        return ;
    }
}t1,t2,t3;
int a1[maxn],a2[maxn],a3[maxn];

struct node
{
    int x,y;
    inline void make(int _x,int _y){x=_x,y=_y;return ;}
}s[maxn];

signed main()
{
    //freopen("inputs2.in","r",stdin);
    n=read();m=read();
    for(int i=1,x,y;i<=n;i++)
    {
        x=read(),y=read();
        s[i].make(x,y);
    }
    for(int i=1;i<=n;i++)
    {
        a1[i]=(s[i].x*s[i].x%mod)%mod;
        a2[i]=(s[i].y*s[i].y%mod)%mod;
        a3[i]=(s[i].x*s[i].y%mod)%mod;
        t1.update(i,a1[i]);
        t2.update(i,a2[i]);
        t3.update(i,a3[i]);
    }
    int opt=0;
    while(m--)
    {
        opt=read();
        if(opt==1)
        {
            int p=read(),x=read(),y=read();
            s[p].x=x,s[p].y=y;
            int c1=a1[p],c2=a2[p],c3=a3[p];
            a1[p]=x*x%mod,a2[p]=y*y%mod;a3[p]=x*y%mod;
            t1.update(p,a1[p]-c1);
            t2.update(p,a2[p]-c2);
            t3.update(p,a3[p]-c3);
        }
        else
        {
            int l=read(),r=read();
            int ans=0;
            ans=((t1.query(r)-t1.query(l-1)+mod)%mod*(t2.query(r)-t2.query(l-1)+mod)%mod+mod)%mod;
            int tt=((t3.query(r)-t3.query(l-1)+mod)%mod+mod)%mod;
            ans=((ans-tt*tt%mod+mod)%mod+mod)%mod;
            printf("%lld\n",ans);
        }
    }
    return 0;
}
View Code

 

T3code

就是一個LCIS,當時學的時候還被人消費來着(LSC  LCIS)而後在看出是dp以後因爲剩的時間過少,還想調T2因此直接打的爆搜,按說應該能夠20分,可是隻有10分,blog

3
考慮 DP. 設狀態 dp(i, j) 表示 a 序列考慮到 i, b 序列考慮到 j 而且必須選 b j 的最
大長度. 當 a i = b j 時, 顯然有轉移 dp(i, j) = max k<j,b k <b j {dp(i − 1, k)} + 1.
因而從小到大枚舉 j, 維護 max k<j,b k <a i {dp(i − 1, k)}, 直接轉移便可.
時間複雜度 O(nm).
get

 

因爲前幾場考試T1過於水,致使以前的T1都切了,並且通常20分鐘以內就能夠A,因此此次T1拖了1個小時,就心態炸了,仍是要歷練!@……@input

 

#include<bits/stdc++.h>
using namespace std;
#define re register
#define LL long long
template<class T>
inline void read(T &x)
{
    T f=1;x=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    x=x*f;
}
int n,m;
const int maxn=5005;
LL a[maxn],b[maxn];
bool vis[maxn];
int ch[maxn],tot;
int dp[maxn][maxn];
int pre[maxn][maxn];
int sta[maxn],topp;
inline void ba(re int x,re int y)
{
    if(x==0||y==0)return;
    re int qq=pre[x][y];
    if(y!=qq)sta[++topp]=b[y];
    ba(x-1,qq);
}
signed main()
{
    //freopen("inputs3.in","r",stdin);
    read(n);
    for(re int i=1;i<=n;i++)
        read(a[i]);
    read(m);
    for(re int i=1;i<=m;i++)
        read(b[i]);    
    for(re int i=1;i<=n;i++)
    {
        int res=0,id=0;
        if(b[0]<b[1])res=dp[i-1][0],id=0;
        for(re int j=1;j<=m;j++)
        {
            if(a[i]==b[j])
            {
                pre[i][j]=id;
                dp[i][j]=res+1;
            }
            else 
            {
                pre[i][j]=j;
                dp[i][j]=dp[i-1][j];
            }
            if(b[j]<a[i])
            {
                if(res<=dp[i-1][j])
                {
                    res=dp[i-1][j],id=j;
                }
            }
        }
    }
    int ans=0,id=0;
    for(re int i=1;i<=m;i++)
    {
        if(dp[n][i]>=ans)ans=dp[n][i],id=i;
    }
    printf("%d\n",dp[n][id]);
    ba(n,id);
    while(topp)
    {
        printf("%d ",sta[topp]);
        topp--;
    }
    return 0;
}
View Code
相關文章
相關標籤/搜索