2.13模拟总结
文章目錄
- 前言
- 題目解析
- 最小劃分(divide)
- 進制路徑(base)
- 歐拉歐拉(eular)
- 代碼
- T1
- T2
- T3
- 總結
前言
day9
170pts
期望:100+100+20=220
實際:70+100+0=170
rnk7
掛的分有點多qwq
分數要是得滿就能拿牌子樂…
T1加了個畫蛇添足的東西,導致白給了30
T3暴搜T掉了,需要引以為戒,其實加個小優化就行了。
題目解析
最小劃分(divide)
應該算是科技題吧。
WQS二分模板題,由于這個算法不是太冷門,A的人也非常多。
選取個數還是要按照 >= 二分…
而且,不要在個數不等于 mmm 的時候強制轉移!本來啥也不干就是對的。
結合WQS的實質也是合理的,只是恰好多個點落在了這條直線上,不影響我用截距求出函數值,如果我最后一步強制按照取 mmm 個轉移,就會破壞最優性,得到錯誤的截距。
理解至上。
進制路徑(base)
爆肝碼農題。
但做法確實不太難想,用主席樹和線段樹二分模擬一下高精加與比較即可。
但是加法需要一個區間推平操作,帶懶標記的主席樹是真的惡心…
時空復雜度應該都是 O((n+m)log?nlog?V)O((n+m)\log n\log V)O((n+m)lognlogV),從加法操作的次數來看空間看起來似乎只有 O(mlog?V)O(m\log V)O(mlogV),但是由于其他的查詢操作需要 pushdown,開更多的點,所以其實空間復雜度也是兩個 log 的。
題解的實現是直接把推平的區間鏈接到一棵空的線段樹的對應結點上,可以把空間復雜度優化到單log。
歐拉歐拉(eular)
真不是我磕巴
KH這題做法真的踩標算了,請收下我的膝蓋!
之前莫反做的挺明白的,這題沒做出來有些可惜。
主要就是腦子有點抽筋了,對于多個數的 lcm,忘記它還可以是每個質因子冪次的最大值。
由于歐拉函數是積性函數,可以單獨考慮枚舉每一個質數 ppp 的貢獻。
我們有:φ(pk)=pk?1(p?1)\varphi(p^k)=p^{k-1}(p-1)φ(pk)=pk?1(p?1)
因此 ppp 這個質數的總貢獻必然是 (p?1)apb(p-1)^ap^b(p?1)apb 的樣子。
首先,ppp 必然要出現至少一次,這樣的序列有 nk??np?kn^k-\lfloor\frac{n}{p}\rfloor^knk??pn??k 個。
因此 p?1p-1p?1 的貢獻冪次 aaa 就是 nk??np?kn^k-\lfloor\frac{n}{p}\rfloor^knk??pn??k。
然后考慮如何求 bbb。
一開始所有序列的貢獻都是 0。
設一個序列中 ppp 的最高次數為 mxmxmx,那么 mx≥wmx\ge wmx≥w 的序列應該有 nk??npw?kn^k-\lfloor\frac{n}{p^w}\rfloor^knk??pwn??k 個。
我們從 2 開始枚舉 www,然后每次把對應的序列的貢獻視為 1。
那么一個 mx=xmx=xmx=x 的序列,其就會貢獻 x?1x-1x?1 次貢獻,正好符合題意。(這也算是一種統計的常見技巧了)
大道至簡,優美。
總復雜度大概是小于單log的。
看完這個做法,題解的做法就…
但是這個 min-max 容斥還挺秀的。
后面就是比較常規的大反演了。
代碼
T1
#include<bits/stdc++.h> using namespace std; #define ll __int128 #define ull unsigned long long #define debug(...) fprintf(stderr,__VA_ARGS__) #define ok debug("OK\n") inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f; } void write(ll x){if(x>9) write(x/10);putchar('0'+x%10); } const int N=2e5+100;int n,m;#define X(o) (2*s[o]) #define Y(o) (dp[o]+s[o]*s[o]-2*p*s[o])ll s[N],dp[N],p; int num[N],q[N],st,ed;void solve(ll w,int op=0){q[st=ed=1]=0;for(int i=1;i<=n;i++){while(st<ed&&s[i]*(X(q[st+1])-X(q[st]))>=(Y(q[st+1])-Y(q[st]))) ++st;int j=q[st];dp[i]=dp[j]+(s[i]-s[j]+p)*(s[i]-s[j]+p)+w;num[i]=num[j]+1;while(st<ed&&(Y(i)-Y(q[ed]))*(X(q[ed])-X(q[ed-1]))<=(Y(q[ed])-Y(q[ed-1]))*(X(i)-X(q[ed]))) --ed;q[++ed]=i;//printf("i=%d j=%d dp=%lld (%lld %lld)\n",i,j,dp[i],X(i),Y(i));//for(int j=st;j<=ed;j++) printf("%d:(%lld %lld) ",q[j],X(q[j]),Y(q[j]));//puts("\n");}//printf("w=%lld num=%d dp=%lld\n",w,num[n],dp[n]);return; }signed main(){freopen("divide.in","r",stdin);freopen("divide.out","w",stdout);n=read();m=read();p=read();for(int i=1;i<=n;i++) s[i]=read()+s[i-1];//solve(308);return 0;ll st=-1e16,ed=1e16;while(st<ed){ll mid=(st+ed+1)>>1;solve(mid);if(num[n]>=m) st=mid;else ed=mid-1;}solve(st,1);write(dp[n]-m*st);return 0; } /* 5 aabba */T2
#include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define debug(...) fprintf(stderr,__VA_ARGS__) #define ok debug("OK\n") inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f; } void write(ll x){if(x>9) write(x/10);putchar('0'+x%10); } const int N=2e5+100; const int mod=1e9+7;int n,m,s,t,o;struct node{int to,nxt,w; }p[N<<1]; int fi[N],cnt; inline void addline(int x,int y,int w){p[++cnt]=(node){y,fi[x],w};fi[x]=cnt; } int pre[N],a[N],num; void print(int x){if(pre[x]) print(pre[x]);a[++num]=x; } ll dis[N]; ull mi[N]; int u[N],v[N],ww[N]; int vis[N]; #define pr pair<ll,int> #define mkp make_pair priority_queue<pr,vector<pr>,greater<pr> >q;void bf(){mi[0]=1;for(int i=1;i<=o;i++) mi[i]=mi[i-1]<<1;for(int i=1;i<=m;i++){addline(u[i],v[i],mi[ww[i]]);addline(v[i],u[i],mi[ww[i]]);}memset(dis,0x3f,sizeof(dis));dis[s]=0;q.push(mkp(0,s));while(!q.empty()){int now=q.top().second;q.pop();if(vis[now]) continue;vis[now]=1;for(int i=fi[now];~i;i=p[i].nxt){int to=p[i].to;if(dis[to]>dis[now]+p[i].w){dis[to]=dis[now]+p[i].w;q.push(mkp(dis[to],to));pre[to]=now;}}}if(pre[t]||s==t){printf("%lld\n",dis[t]%mod);print(t);printf("%d\n",num);for(int i=1;i<=num;i++) printf("%d ",a[i]);puts("");}else puts("-1");return; }ull hh[N][2]; #define mid ((l+r)>>1) const int key=3; struct tree{int ls,rs,sum,laz;ull h; }tr[N*200]; int tot; inline void pushup(int k,int l,int r){tr[k].sum=tr[tr[k].ls].sum+tr[tr[k].rs].sum;tr[k].h=tr[tr[k].rs].h*mi[mid-l+1]+tr[tr[k].ls].h;return; } inline int copy(int x){tr[++tot]=tr[x];return tot; } inline void add(int &k,int l,int r,int w){k=copy(k);tr[k].sum=(r-l+1)*w;tr[k].laz=w;tr[k].h=hh[r-l+1][w];return; } inline void pushdown(int k,int l,int r){if(l==r) return;int o=tr[k].laz;tr[k].laz=-1;if(o==-1) return;add(tr[k].ls,l,mid,o);add(tr[k].rs,mid+1,r,o);return; } void build(int &k,int l,int r,int w){k=copy(0);if(l==r){tr[k].sum=tr[k].h=w;hh[r-l+1][w]=tr[k].h;return;}build(tr[k].ls,l,mid,w);build(tr[k].rs,mid+1,r,w);pushup(k,l,r);hh[r-l+1][w]=tr[k].h;return; } int findsuf(int k,int l,int r,int pl){if(tr[k].sum==r-l+1) return r-pl+1;if(l==r) return 0;pushdown(k,l,r);if(pl>mid) return findsuf(tr[k].rs,mid+1,r,pl);else{int res=findsuf(tr[k].ls,l,mid,pl);if(res==mid-pl+1) return res+findsuf(tr[k].rs,mid+1,r,mid+1);else return res;} } void upd(int &k,int l,int r,int x,int y,int w){//printf("upd: (%d %d) (%d %d) w=%d\n",l,r,x,y,w);if(x>y) return;if(x<=l&&r<=y){add(k,l,r,w);return;}pushdown(k,l,r);k=copy(k);if(x<=mid) upd(tr[k].ls,l,mid,x,y,w);if(y>mid) upd(tr[k].rs,mid+1,r,x,y,w);pushup(k,l,r);return; } bool cmp(int x,int y,int l,int r){// x<y ? 1:0if(tr[x].h==tr[y].h) return 0;if(l==r) return tr[x].sum<tr[y].sum;pushdown(x,l,r);pushdown(y,l,r);if(tr[tr[x].rs].h!=tr[tr[y].rs].h) return cmp(tr[x].rs,tr[y].rs,mid+1,r);else return cmp(tr[x].ls,tr[y].ls,l,mid); } struct bign{int rt;void plus(int w){int len=findsuf(rt,1,o,w);upd(rt,1,o,w,w+len-1,0);upd(rt,1,o,w+len,w+len,1);return;}bool operator < (const bign &oth)const{return cmp(rt,oth.rt,1,o);} }d[N]; struct Dis{bign dis;int id;bool operator < (const Dis &oth)const{if(tr[dis.rt].h==tr[oth.dis.rt].h) return id>oth.id;else return oth.dis<dis;} }; priority_queue<Dis>que; ll ans,mi2[N]; void calc(int k,int l,int r){if(l==r){ans=(ans+tr[k].sum*mi2[l-1])%mod;return;}pushdown(k,l,r);calc(tr[k].ls,l,mid);calc(tr[k].rs,mid+1,r);return; } void solve(){o+=20;mi2[0]=1;for(int i=1;i<=o;i++) mi2[i]=(mi2[i-1]<<1)%mod;mi[0]=1;for(int i=1;i<=o;i++) mi[i]=mi[i-1]*key;for(int i=1;i<=m;i++){++ww[i];addline(u[i],v[i],ww[i]);addline(v[i],u[i],ww[i]);}build(d[0].rt,1,o,1);//rt[0]=inffor(int i=1;i<=n;i++) d[i].rt=d[0].rt;build(d[s].rt,1,o,0);que.push((Dis){d[s],s});while(!que.empty()){int now=que.top().id;que.pop();if(vis[now]) continue;vis[now]=1;for(int i=fi[now];~i;i=p[i].nxt){int to=p[i].to,w=p[i].w;bign res=d[now];res.plus(w);if(res<d[to]){d[to]=res;que.push((Dis){d[to],to});pre[to]=now;}}}if(!pre[t]&&s!=t) puts("-1");else{calc(d[t].rt,1,o);//debug("dis=%lld\n",ans);printf("%lld\n",ans);print(t);printf("%d\n",num);for(int i=1;i<=num;i++) printf("%d ",a[i]);}return; }signed main(){freopen("base.in","r",stdin);freopen("base.out","w",stdout);//printf("%d\n",sizeof(tr)/1024/1024);memset(fi,-1,sizeof(fi));cnt=-1;tr[0].laz=-1;n=read();m=read();s=read();t=read();for(int i=1;i<=m;i++){u[i]=read();v[i]=read();ww[i]=read();o=max(o,ww[i]);}if(o<=20) bf();else solve();//solve();return 0; } /* 5 aabba */T3
#include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define debug(...) fprintf(stderr,__VA_ARGS__) #define ok debug("OK\n") inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f; } void write(ll x){if(x>9) write(x/10);putchar('0'+x%10); } const int N=2e6+100; const int mod=1e9+7;inline ll ksm(ll x,ll k,ll mod){ll res(1);while(k){if(k&1) res=res*x%mod;x=x*x%mod;k>>=1;}return res; }int n,k; int prime[N],vis[N],tot; void init(int n){++n;for(int i=2;i<=n;i++){if(!vis[i]){prime[++tot]=i;}for(int j=1;j<=tot&&prime[j]<=n/i;j++){int now=prime[j];vis[i*now]=1;if(i%now==0) break;}}return; }signed main(){freopen("euler.in","r",stdin);freopen("euler.out","w",stdout);n=read();k=read();init(max(k,n));ll ans(1);for(int o=1;o<=tot;o++){ll p=prime[o];ans=ans*ksm(p-1,ksm(n,k,mod-1)+(mod-1)-ksm(n-n/p,k,mod-1),mod)%mod;ll now=p*p;while(now<=n){ans=ans*ksm(p,ksm(n,k,mod-1)+mod-1-ksm(n-n/now,k,mod-1),mod)%mod;now*=p;}}printf("%lld\n",ans);return 0; } /* 5 aabba */總結
今天感覺整體題目要偏易一些。
但是掛的分有點多了,而且T3實屬可惜,其實對每個質數單獨考慮的做法我也不是沒有想過…
(現在對題目的“感覺”還是變好了一些,做不出的題見到solution也基本上都有“其實想過”的過程。)
但是還是要敢推敢想吧。
既要敢于創造性的思考,也要在遇阻時嘗試多線思維。
另外,今天節奏還是不錯的。
明天加油吧!awa
總結
- 上一篇: 字节跳动开启新一轮期权回购,在职员工为
- 下一篇: 2.14模拟总结