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\n",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\n",ans); return 0; }