19-11-13-;
中午起来困傻了,写五分钟反思提下神智不轻的麦蒙
时间真快呀。
$$
\begin{array}{lr}
I\ wished\ upon\ a\ star\ and\ thought\ of\ you & \\
But\ it\ is\ a\ dream\ 'cause\ you're\ not\ here\ . & \\
&\ One\ Less\ Star
\end{array}
$$记不清作者了
ZJ:
考试前平复心情……
开考简单看了一眼第一页(话说这是第一个把名字写在题目前的作者)
打$\text{vimrc}$
然后开T1。
……
六边形????????
不是很清楚。
于是先拿了特殊性质的10分。(做法正确!)
仿佛发现点什么东西。
今天风太巨了(奶风),于是有点闹肚,去厕所玩耍完善思路
觉得是贪心思路,先摆一个大正六边形,然后扩边。
手玩几个点都过了。
T2不会,先想了半天是从$f_i$到$i$还是从$i$到$f_i$建边。
T3先想了$Hash$,但是写了一会发现自己不会合并两侧的$hash$值
于是果断放弃,用 string 巨暴力拿到20。剪枝也没来得及打。
string 的几个函数。
1.erase(a,b)
可以从$a$开始删,删$b$个字符(本来以为左闭右开结果不是)
如$toot$ erase(2,2) 变为 $to$
2. substr(a,b)
返回从$a$开始,长度为$b$的子串
3. insert(a,str)
在$a$处插入一个字符串$str$,原序列依次后移。
如$toot$ insert(2,"toot") 变为$totootot$
14
|
Miemeng | 100
00:00:19
|
30
00:00:19
|
20
00:00:20
|
150
00:00:20
|
这年头能不挂分就是谢天谢地了……
TJ:
怕咕咕咕之后死。
T1:
考场$1h$解决。
直接二分蒸馏变形正六边形下界,贪心扩边就ok。
复杂度:$\Theta(\log N)$
所以此题出到$N \leq 10^{18}$没有问题。(逃
对于那些$\Theta(1)$的大佬此题甚至可以$N \leq 10^{100000 \dots}$(高精预警(再逃
#include <iostream> #include <cstring> #include <cstdio> #define LL long long using namespace std; LL fn,nans; LL getval(int x){ return 6ll*x*(x-1)/2+1;//这个是边长为k的蒸馏变形的占格数 } LL getk(LL v){//二分边长 LL l=1,r=100000; while(l<r){ LL mid=(l+r+1)/2; if(getval(mid)<=v)l=mid; else r=mid-1; } return l; } int main(){ #ifndef LOCAL freopen("wall.in" ,"r",stdin); freopen("wall.out","w",stdout); #endif ios_base::sync_with_stdio(false); cin>>fn; LL k=getk(fn); if(fn==getval(k)){//把10分稳住 cout<<getval(k+1)-getval(k)<<endl; } else{ k++; LL lft=fn-getval(k-1); if(k==2){ cout<<getval(k)-getval(k-1)+lft+1<<endl;//二的贡献不好处理,特判掉 } else{ LL ede=k-2,lft=fn-getval(k-1); for(int i=1;i<6;i++){ if(ede*i+i-1>=lft){ cout<<getval(k)-getval(k-1)+i<<endl; return 0; } } cout<<getval(k+1)-getval(k)<<endl; } } }
T2:
码死我了。
其实此题所用的是拓扑,$dfs$处理环,构造建图的思想。
但是其实不用真正拓扑,不用真正$dfs$,也不用真正建图(捂脸
但是我还是打了拓扑,$dfs$处理环,构造建图。
所以我累死了。
首先我们将$i$向$f_i$建边。
这样我们就可以用$i$的$C$去更新$f_i$的答案。
那么我们就已经处理好链的答案了。
下面我们要考虑环。
环很难搞。
首先如果环上的边不优我们可以直接拆环。
如果拆不掉
我们需要用两种值更新环上点的答案,
一种是用次小消耗(一定不在环上)代替(环上的)最小消耗所损失的答案。
另一种是没有其他代替方法,只能留下一个物品所损失的答案。
简单判下就可以了。
#include <iostream> #include <cstring> #include <climits> #include <cstdio> #include <vector> #define N 111111 #define LL long long using namespace std; struct Myqueue{ int A[10*N]; int f,b; Myqueue(){f=b=0;} void clear(){f=b=0;} void push(const int k){A[b++]=k;} void pop(){f++;} int front(){return A[f];} bool empty(){return f==b;} int size(){return b-f;} }q; struct SR{ int f,t,next; }rs[2*N]; int itn,fl[N],cnt=0; int lop[N],deg[N]; vector <int> lp; bool is_d[N]; LL op[N],cst[N],val[N],num[N]; LL minlp[N],minst[N],ans; void add(int f,int t){ rs[cnt].f=f; rs[cnt].t=t; rs[cnt].next=fl[f]; fl[f]=cnt++; } void dfs(int k,const int id){ lp.push_back(k); lop[k]=id; for(int i=fl[k];i!=-1;i=rs[i].next){ int t=rs[i].t; minlp[t]=min(minlp[t],cst[k]); if(!lop[t]) dfs(t,id); } } void topsort(){ for(int i=1;i<=itn;i++) if(deg[i]==0) q.push(i); while(!q.empty()){ int f=q.front();q.pop(); for(int i=fl[f];i!=-1;i=rs[i].next){ int t=rs[i].t; deg[t]--; minst[t]=min(minst[t],cst[f]); if(deg[t]==0) q.push(t); } } } int main(){ #ifndef LOCAL freopen("goods.in" ,"r",stdin); freopen("goods.out","w",stdout); #endif ios_base::sync_with_stdio(false); memset(fl,-1,sizeof fl); memset(minlp,0x3f,sizeof minlp); memset(minst,0x3f,sizeof minst); cin>>itn; for(int i=1;i<=itn;i++){ cin>>op[i]>>cst[i]>>val[i]>>num[i]; add(i,op[i]); deg[op[i]]++; } topsort(); for(int i=1;i<=itn;i++){ if(deg[i]==0){ if(val[i]>minst[i]) ans+=(val[i]-minst[i])*num[i]; } else if(!lop[i]){//cout<<i<<endl; lp.clear(); dfs(i,i); if(lp.size()==1){ LL aminn=min(minlp[i],minst[i]); if(aminn<val[i]) ans+=(val[i]-aminn)*num[i]; continue; } bool des=0; for(int i=0;i<(int)lp.size();i++){ if(min(minlp[lp[i]],minst[lp[i]])>val[lp[i]]){ //cout<<"Kill!"<<i<<endl; is_d[lp[i]]=1; des=1; } else if(minst[lp[i]]<=minlp[lp[i]]){ ans+=(val[lp[i]]-minst[lp[i]])*num[lp[i]]; is_d[lp[i]]=1; des=1; } } //cout<<des<<endl; if(des){ for(int i=0;i<(int)lp.size();i++){ if(!is_d[lp[i]]) ans+=(val[lp[i]]-minlp[lp[i]])*num[lp[i]]; else is_d[lp[i]]=0; } } else{ LL minans=LLONG_MAX,minval=LLONG_MAX; for(int i=0;i<(int)lp.size();i++){ ans+=(val[lp[i]]-minlp[lp[i]])*num[lp[i]]; minans=min(minans,minst[lp[i]]-minlp[lp[i]]); minval=min(minval,val[lp[i]]-minlp[lp[i]]); // cout<<"Va:"<<val[lp[i]]<<endl; // cout<<"Mp:"<<minlp[lp[i]]<<endl; // cout<<"De:"<<val[lp[i]]-minlp[i]<<endl; } if(minans<=minval) ans-=minans; else ans-=minval; } } } cout<<ans<<endl; }