JNday3-pm


T1
这个题就是找规律
出现大于等于两个环的时候方案数为0
当时章鱼图的时候,分配方案唯一确定,方案数为2
没有环的图—>树—>方案数=点数(总会有一个点没有被分配到)
然后我们可以并查集维护联通性
and then 搞定

T2
第一眼看到这道题很蒙蔽,(还有这种操作!!!),细想一下
真是zz,对于任意负数,当它有偶数指数的就是正的 ( 我貌似在说一些没有人会不知道的东西 )
那么只要所有偶数为上是0,就搞定啦呀(偶数位上的指数是奇数,那我们就不要他呀)
想到这里,貌似一个计算模拟就可以计算出answer,然而标程用数位dp(haha)

T3
然后对于T3,30min写完一个贪心的算法然而只有30分,(贪心思路:可以找到每条链深度最深的点,
将这些点记录下来,一共js个,因为可以走k次,那么贪心的选在这些点中会有js - k 个点不会走
,这些点就是点权最小的那些点。)//因为你的-1,所以没有人会L听你错误的思路,你只配说给自己听
正解(瞎扯淡贪心×)://记住:别人可以see you and no resut(毕竟这是你无法掌控的),但是没有人可以使你低头
对于这道题,我们暴力寻找点权之和最大的路径,每次只会影响一段连续的区间,这样可以线段树维护,
懒标记打为是否曾经删除过

T1  少女

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll long long
#define ha 1000000007
#define pb push_back
using namespace std;
#define maxn 100005

vector<ll> g[maxn];
ll ans=1,n,m;
ll f[maxn][2];
bool vis[maxn];
ll ban[maxn];
ll po1,po2;

inline ll ksm(ll x,ll y){
    ll an=1;
    for(;y;y>>=1,x=x*x%ha) if(y&1) an=an*x%ha;
    return an;
}

inline ll read(){
    ll x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}

void work(ll x,ll fa){
    vis[x]=1;
    ll v,tt=0;
    for(int i=g[x].size()-1;i>=0;i--){
        v=g[x][i];
        if(v==fa&&v!=x&&!tt){
            tt++;
               continue;
        }
        
        if(vis[v]){
            po1=x,po2=v;
            ban[x]=v,ban[v]=x;
        }
        else work(v,x);
    }
}

void dfs(ll x,ll fa){
    f[x][0]=f[x][1]=0;
    ll v,tmp=1;
    
    for(int i=g[x].size()-1;i>=0;i--){
        v=g[x][i];
        if(v==fa||v==ban[x]) continue;
        
        dfs(v,x);
        tmp=tmp*f[v][0]%ha;
    }
    
    f[x][0]=f[x][1]=tmp;
    
    for(int i=g[x].size()-1;i>=0;i--){
        v=g[x][i];
        if(v==fa||v==ban[x]) continue;
        
        f[x][1]=(f[x][1]+tmp*f[v][1]%ha*ksm(f[v][0],ha-2))%ha;
    }    
}

int main(){
    freopen("girl.in","r",stdin);
    freopen("girl.out","w",stdout);
    
    ll uu,vv;
    n=read(),m=read();
    for(int i=1;i<=m;i++){
        uu=read(),vv=read();
        g[uu].pb(vv),g[vv].pb(uu);
    }
    
    for(int i=1;i<=n;i++) if(!vis[i]){
        po1=po2=0;
        
        work(i,i);
        ll tot;
        if(po1&&po2){
            dfs(po1,po1);
            tot=f[po1][0];
            dfs(po2,po2);
            tot=(tot+f[po2][0])%ha;
        }
        else{
            dfs(i,i);
            tot=f[i][1];
        }
        
        ans=ans*tot%ha;
    }
    
    cout<<ans<<endl;
    return 0;
}

T2 终末

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll long long
using namespace std;
ll n,k;
ll a[70],len=0,ans=0;

inline ll ksm(ll x,ll y){
    if(!x) return 0;
    
    ll an=1;
    for(;y;y>>=1,x*=x) if(y&1) an*=x;
    return an;
}

int main(){
    freopen("endless.in","r",stdin);
    freopen("endless.out","w",stdout);
    
    cin>>n>>k;
    while(n) a[++len]=n%k,n/=k;
    
    if(!(len&1)){
        printf("%I64d
",ksm(k,len/2));
        return 0;
    }
    
    int i;
    for(i=len;i;i--) if(i&1){
        ans+=a[i]*ksm(k,i/2);
    }else if(a[i]){
        ans+=ksm(k,i/2);
        break;
    }
    
    if(!i) ans++;
    
    cout<<ans<<endl;
    return 0;
}

T3 旅行

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<algorithm>
 
using namespace std;
 
const int BUF_SIZE = 30;
char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1;
   
#define PTR_NEXT() 
    { 
        buf_s ++; 
        if (buf_s == buf_t) 
        { 
            buf_s = buf; 
            buf_t = buf + fread(buf, 1, BUF_SIZE, stdin); 
        } 
    }
    
#define readint(_n_) 
    { 
        while (*buf_s != '-' && !isdigit(*buf_s)) 
            PTR_NEXT(); 
        bool register _nega_ = false; 
        if (*buf_s == '-') 
        { 
            _nega_ = true; 
            PTR_NEXT(); 
        } 
        int register _x_ = 0; 
        while (isdigit(*buf_s)) 
        { 
            _x_ = _x_ * 10 + *buf_s - '0'; 
            PTR_NEXT(); 
        } 
        if (_nega_) 
            _x_ = -_x_; 
        (_n_) = (_x_); 
    }
 
#define wmt 1,cnt,1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
 
const int maxn=200010;
 
int n,k,en,z[maxn],f[maxn],s[maxn],leaf[maxn],l[maxn],r[maxn];
 
long long y[maxn<<2|1],col[maxn<<2|1];
 
bool del[maxn];
 
struct edge
{
    int e;
    edge *next;
}*v[maxn],*ve[maxn],ed[maxn];
 
inline void add_edge(int s,int e)
{
    en++;
    ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;
}
 
#define update(rt) y[rt]=max(y[rt<<1],y[rt<<1|1]);
 
#define push_col(rt)
    if (col[rt])
    {
        col[rt<<1]+=col[rt];y[rt<<1]+=col[rt];
        col[rt<<1|1]+=col[rt];y[rt<<1|1]+=col[rt];
        col[rt]=0;
    }
 
inline void modify(int l,int r,int rt,int nowl,int nowr,int delta)
{
    if (nowl<=l && r<=nowr)
    {
        y[rt]+=delta;
        col[rt]+=delta;
        return;
    }
    push_col(rt);
    int m=(l+r)>>1;
    if (nowl<=m) modify(lson,nowl,nowr,delta);
    if (m<nowr) modify(rson,nowl,nowr,delta);
    update(rt);
}
 
inline int query(int l,int r,int rt)
{
    if (l==r) return l;
    push_col(rt);
    int m=(l+r)>>1;
    if (y[rt<<1]>y[rt<<1|1]) return query(lson);
    else return query(rson);
}
 
int main()
{
    freopen("tour.in","r",stdin);
    freopen("tour.out","w",stdout);

    readint(n);
    readint(k);
    for (int a=1;a<=n;a++)
    {
        readint(z[a]);
    }
    for (int a=1;a<n;a++)
    {
        int p1,p2;
        readint(p1);
        readint(p2);
        f[p2]=p1;
        add_edge(p1,p2);
    }
    int root;
    for (int a=1;a<=n;a++)
        if (!f[a]) root=a;
    int size=1;
    s[1]=root;
    for (int a=1;a<=n;a++)
        ve[a]=v[a];
    memset(l,0x3f,sizeof(l));
    int cnt=0;
    while (size)
    {
        int now=s[size];
        if (!ve[now])
        {
            if (!v[now]) 
            {
                l[now]=r[now]=++cnt;
                leaf[cnt]=now;
            }
            l[f[now]]=min(l[f[now]],l[now]);
            r[f[now]]=max(r[f[now]],r[now]);
            size--;
        }
        else
        {
            size++;
            s[size]=ve[now]->e;
            ve[now]=ve[now]->next;
        }
    }
    for (int a=1;a<=n;a++)
        modify(wmt,l[a],r[a],z[a]);
    k=min(k,cnt);
    long long ans=0;
    for (int a=1;a<=k;a++)
    {
        int p=query(wmt);
        p=leaf[p];
        while (!del[p] && p)
        {
            modify(wmt,l[p],r[p],-z[p]);
            ans+=z[p];
            del[p]=true;
            p=f[p];
        }
    }
    printf("%I64d
",ans);
 
    return 0;
}
原文地址:https://www.cnblogs.com/lyqlyq/p/7757809.html