1. 程式人生 > 其它 >DAY 160 xshell常用命令大全

DAY 160 xshell常用命令大全

A. 入陣曲

很經典的一道題目,維護具有特殊性質的字首和,這個方法很常用..其實也是對字首和特點的一種應用..

本題中維護模 k 相同的字首和即可..

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define lf double
#define mp make_pair
inline void read(ll &ss)
{
    ss=0; bool cit=0; char ch;
    while(!isdigit(ch=getchar())) if(ch=='-') cit=1
; while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar(); if(cit) ss=-ss; } ll n,m,mod,ans; ll a[500][500]; ll pre[500][500]; ll f[(int)1e7]; ll g[(int)1e7]; signed main() { read(n); read(m); read(mod); for(ll i=1;i<=n;i++) { for(ll j=1;j<=m;j++) { read(a[i][j]); pre[i][j]
=(pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i][j]+mod*10)%mod; } } for(ll i=0;i<=n;i++) { for(ll j=i+1,cnt=0;j<=n;j++,cnt=0) { f[0]=1; for(ll k=1,temp;k<=m;k++) { temp=(pre[j][k]-pre[i][k]+mod*10)%mod; g[
++cnt]=temp; ans+=f[temp]; f[temp]++; } for(ll k=1;k<=cnt;k++) f[g[k]]=0; } } printf("%lld",ans); return 0; } /* 2 3 2 1 2 1 2 1 2 */
A_Code

B. 將軍令

可以考慮樹形dp:我們可以很明顯地觀察到,如果 k 全部都等於 1,那麼很像之前做過的一道題《小胖守皇宮》,本題維護一下被 j 級子孫,j 級祖先對自己的影響即可..這裡安利 Yubai 大佬的部落格..

另外考慮貪心..我們發現一個性質:無論何時,我們選擇 k 級祖先來維護自己是最優的答案。用反證法證明,如果我們選擇了比 k 級祖先更低的點來維護自己,那麼一定會有更多維護能力被浪費掉,因為 k 級祖先維護的範圍才是最廣的..

而我考場上只打了一個爆搜,其實加個記憶化就能 A,但是根本想不到,所以這裡劃重點:打爆搜一定要想想記憶化減枝

#include<bits/stdc++.h>
using namespace std;
#define ll int
#define lf double
#define mp make_pair
const ll N=1e5+50;
inline void read(ll &ss)
{
    ss=0; bool cit=0; char ch;
    while(!isdigit(ch=getchar())) if(ch=='-') cit=1;
    while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
    if(cit) ss=-ss;
}
ll n,maxn,sp,ans,ts;
ll head[N];
bool vis[N];
struct I { ll u,v,nxt; } a[N*20];
struct II { ll dep,num; } g[N+50];
bool operator <(const II &aa,const II &bb)
{
    if(aa.dep==bb.dep) return aa.num<bb.num;
    return aa.dep<bb.dep;
}
priority_queue<II> que;
inline void add(ll u,ll v)
{
    a[++ts].u=u;
    a[ts].v=v;
    a[ts].nxt=head[u];
    head[u]=ts;
}
ll find(ll now,ll left)
{
    if(left==0 or now==0) return now;
    for(ll i=head[now];i;i=a[i].nxt)
    {
        if(i and g[a[i].v].dep<g[now].dep) return find(a[i].v,left-1);
    }
}
void dfs_depth(ll now,ll depth)
{
    vis[now]=true;
    g[now].num=now; g[now].dep=depth;
    que.push(g[now]);
    for(ll i=head[now];i;i=a[i].nxt)
    {
        if(vis[a[i].v]) continue;
        dfs_depth(a[i].v,depth+1);
    }
    return ;
}
void dfs(ll dad,ll now,ll left)
{
    vis[now]=true;
    if(left==0 or now==0) return ;
    for(ll i=head[now];i;i=a[i].nxt)
    {
        if(a[i].v==dad) continue;
        dfs(now,a[i].v,left-1);
    }
    return ;
}
signed main()
{
    read(n); read(maxn); read(sp);
    ll u,v;
    for(ll i=1;i<=n-1;i++)
    {
        read(u); read(v);
        add(u,v); add(v,u);
    }
    dfs_depth(1,1);
    memset(vis,0,sizeof vis);
    II temp; ll tem;
    while(!que.empty())
    {
        temp=que.top(); que.pop();
        if(vis[temp.num]) continue; ans++;
        tem=find(temp.num,maxn); dfs(tem,tem,maxn);
    }
    printf("%d",ans);
    return 0;
}
B_Code

C. 星空

又是一道觀察性質的題目..(大概是因為我太菜,一到這類題就只能認為是觀察性質,怎麼想都想不到..)

觀察 k 的範圍,理應想到狀壓..

然後考慮題目的特點:發現可以類比’開心消消樂‘..(題解裡面還管這個叫廣義字首和,不過想一想還真的是有用到字首和的特點..)

#include<bits/stdc++.h>
using namespace std;
#define ll int
#define lf double
#define mp make_pair
const ll N=1e5+50;
inline void read(ll &ss)
{
    ss=0; bool cit=0; char ch;
    while(!isdigit(ch=getchar())) if(ch=='-') cit=1;
    while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
    if(cit) ss=-ss;
}
ll n,m,t,ts;
bool p[N],g[N],vis[N];
ll op[N],pos[N],org[N];
ll head[N],f[1<<20];
ll dis[200][N];
deque<ll> que;
inline void bfs(ll now)
{
    dis[now][pos[now]]=0;
    que.push_back(pos[now]);
    vis[pos[now]]=1; ll x,y;
    while(que.size())
    {
        x=que.front();
        que.pop_front();
        for(ll i=1;i<=t;i++)
        {
            y=x-op[i];
            if(y>0 and dis[now][y]>dis[now][x]+1)
            {
                dis[now][y]=dis[now][x]+1;
                que.push_back(y); vis[y]=1;
            }
            y=x+op[i];
            if(y<=n+1 and dis[now][y]>dis[now][x]+1)
            {
                dis[now][y]=dis[now][x]+1;
                que.push_back(y); vis[y]=1;
            }
        }
        vis[x]=0;
    }
    return ;
}
signed main()
{
    read(n); read(m); read(t);
    ll temp; memset(p,1,sizeof p);
    for(ll i=1;i<=m;i++)
    {
        read(temp); p[temp]=false;
    }
    for(ll i=1;i<=t;i++) read(op[i]);
    sort(op+1,op+1+t);
    temp=0; p[0]=true;
    for(ll i=1;i<=n+1;i++)
    {
        g[i]=p[i] xor p[i-1];
        if(g[i]) pos[++temp]=i,org[i]=temp;
    }
    memset(dis,0x3f,sizeof dis);
    memset(f,0x3f,sizeof f);
    for(ll i=1;i<=temp;i++) bfs(i);
    f[(1<<temp)-1]=0;
    for(ll i=(1<<temp)-1,j,v;i>=0;i--)
    {
        j=1;
        while(((1<<(j-1)) & i)==0 and j<temp) j++;
        for(ll k=j+1;k<=temp;k++)
        {
            if((i & (1<<(k-1)))==0) continue;
            v=(i xor (1<<(j-1))) xor (1<<(k-1));
            f[v]=min(f[v],f[i]+dis[j][pos[k]]);
        }
    }
    printf("%d",f[0]);
    return 0;
}
/*
5 2 2
1 5
3 4

 */
C_Code