Solved | A | HDU 6298 | Maximum Multiple |
Solved | B | HDU 6299 | Balanced Sequence |
Solved | C | HDU 6300 | Triangle Partition |
Solved | D | HDU 6301 | Distinct Values |
E | HDU 6302 | Maximum Weighted Matching | |
F | HDU 6303 | Period Sequence | |
Solved | G | HDU 6304 | Chiaki Sequence Revisited |
Solved | H | HDU 6305 | RMQ Similar Sequence |
I | HDU 6306 | Lyndon Substring | |
J | HDU 6307 | Turn Off The Light | |
Solved | K | HDU 6308 | Time Zone |
A 找規律node
發現只有3和4的倍數有存在答案ios
#include <bits/stdc++.h> #define ll long long #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(ii,a,b) for(int ii=a;ii<=b;ii++) #pragma comment(linker, "/stack:200000000") #pragma GCC optimize("Ofast") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #pragma GCC optimize("unroll-loops") using namespace std; const int maxn=1e5+10; const int maxm=1e6+10; const int INF=0x3f3f3f3f; ll casn,n,m,k; #define tpyeinput ll inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;} inline void read(tpyeinput &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();} inline void read(tpyeinput &num1,tpyeinput &num2){read(num1);read(num2);} inline void read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){read(num1);read(num2);read(num3);} inline void read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){read(num1);read(num2);read(num3);read(num4);} int main(){ //#define test #ifdef test freopen("in.txt","r",stdin);freopen("out.txt","w",stdout); #endif read(casn); while(casn--){ read(n); if(n>=3&&n%3==0) printf("%lld\n",((n/3ll)*(n/3ll)*(n/3ll))); else if(n>=4&&n%4==0) printf("%lld\n",n*n*n/32ll); else puts("-1"); } #ifdef test fclose(stdin);fclose(stdout);system("out.txt"); #endif return 0; }
B 貪心c++
去掉已經配對的,對於剩下 的,左邊括號>右括號的放在左邊,若是一樣是左括號>右括號,不須要管哪一個左括號多,只須要管哪一個右括號少,右括號少的放在左邊oop
#include <bits/stdc++.h> #define ll long long #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(ii,a,b) for(int ii=a;ii<=b;ii++) using namespace std; const int maxn=1e5+10; const int maxm=1e6+10; const int INF=0x3f3f3f3f; int casn,n,m,k; #define tpyeinput int inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;} inline void read(tpyeinput &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();} inline void read(tpyeinput &num1,tpyeinput &num2){read(num1);read(num2);} inline void read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){read(num1);read(num2);read(num3);} inline void read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){read(num1);read(num2);read(num3);read(num4);} string str[maxn]; struct node { int a,b; }s[maxn]; int cmp(node &a,node &b){ int x=min(a.a,b.b),y=min(a.b,b.a); return x>y||x==y&&a.a>b.a; } int main(){ //#define test #ifdef test freopen("in.txt","r",stdin);freopen("out.txt","w",stdout); #endif IO; cin>>casn; while(casn--){ cin>>n; rep(i,1,n){ cin>>str[i]; } int ans=0; rep(i,1,n){ int a=0,b=0; rep(j,0,str[i].size()-1){ if(str[i][j]=='(') a++; else if(str[i][j]==')'){ if(a>0) a--,ans+=2; else b++; } s[i]=(node){a,b}; } } sort(s+1,s+1+n,cmp); int a=0,b=0; rep(i,1,n){ if(a>=s[i].b){ ans+=s[i].b*2; a-=s[i].b; }else { ans+=a*2; a=0; } a+=s[i].a; } cout<<ans<<endl; } #ifdef test fclose(stdin);fclose(stdout);system("out.txt"); #endif return 0; }
C 畫圖,找規律ui
保證三點不共線,畫圖嘗試以後發現規律,把點排序便可(這道題用輸入掛反而會WA?)spa
#include <bits/stdc++.h> #define ll long long #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(ii,a,b) for(int ii=a;ii<=b;ii++) using namespace std; const int maxn=1e5+10; const int maxm=1e6+10; const int INF=0x3f3f3f3f; int casn,n,m,k; //#define tpyeinput int //inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;} //inline void read(tpyeinput &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();} //inline void read(tpyeinput &num1,tpyeinput &num2){read(num1);read(num2);} //inline void read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){read(num1);read(num2);read(num3);} //inline void read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){read(num1);read(num2);read(num3);read(num4);} struct node { int x,y,id; }p[maxn]; bool cmp(node &a,node& b){ if(a.x==b.x) return a.y<b.y; return a.x<b.x; } int main(){ //#define test #ifdef test freopen("in.txt","r",stdin);freopen("out.txt","w",stdout); #endif IO; cin>>casn; while(casn--){ cin>>n; rep(i,1,3*n){ int a,b; cin>>a>>b; p[i]=(node){a,b,i}; } sort(p+1,p+1+3*n,cmp); k=1; rep(i,1,n){ rep(j,1,3){ cout<<p[k++].id<<' '; } cout<<endl; } } #ifdef test fclose(stdin);fclose(stdout);system("out.txt"); #endif return 0; }
D 雙指針/貪心+小根堆維護mex.net
排序要求的區間,而後雙指針遍歷全部便可,用priority_queue維護當前雙指針內的mex指針
卡時間,建議上輸入掛code
#include <bits/stdc++.h> #define ll long long #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(ii,a,b) for(int ii=a;ii<=b;ii++) using namespace std; const int maxn=1e5+10; const int maxm=1e6+10; const int INF=0x3f3f3f3f; const int mod=1e9+7; int casn,n,m,k; #define tpyeinput int inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;} inline void read(tpyeinput &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();} inline void read(tpyeinput &num1,tpyeinput &num2){read(num1);read(num2);} inline void read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){read(num1);read(num2);read(num3);} inline void read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){read(num1);read(num2);read(num3);read(num4);} int ans[maxn]; int pos[maxn]; set<int>num; int main(){ //#define test #ifdef test freopen("in.txt","r",stdin);freopen("out.txt","w",stdout); #endif read(casn); while(casn--){ read(n,m); rep(i,1,n) { ans[i]=1; pos[i]=i; num.insert(i); } rep(i,1,m){ int a,b; read(a,b); pos[b]=min(pos[b],a); } for(int i=n-1;i;i--){ pos[i]=min(pos[i],pos[i+1]); } int last=1; rep(i,1,n){ while(last<pos[i]){ num.insert(ans[last]); last++; } ans[i]=*num.begin(); num.erase(ans[i]); } rep(i,1,n){ printf("%d%c",ans[i]," \n"[i==n]); } } #ifdef test fclose(stdin);fclose(stdout);system("out.txt"); #endif return 0; }
G 找規律+打表倍增blog
找規律發現,數列中$X$的出現次數是$lowbit(X)$,因而對於出現次數相同的值(也就是$lowbit(x)$相同)的數,構成了等差數列..
原數列就是不少個等差數列構成的了,而後先預處理一下值,每次有多少個不一樣的等差數列,求和便可...
具體看代碼
#include <bits/stdc++.h> #define ll long long #define show(x) cout<<#x<<"="<<x<<endl #define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl #define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl #define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl #define show5(v,w,x,y,z) cout<<#v<<" "<<v<<" "<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl #define showa(a,b) cout<<#a<<'['<<b<<"]="<<a[b]<<endl #define print(x) cout<<#x<<"="<<x<<' ' #define ptline() cout<<endl #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(ii,a,b) for(int ii=a;ii<=b;ii++) using namespace std; const int maxn=1e5+10; const int maxm=1e6+10; const ll mod=1e9+7; const int INF=0x3f3f3f3f; ll casn,n,m,k; #define tpyeinput ll inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;} inline void read(tpyeinput &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();} inline void read(tpyeinput &num1,tpyeinput &num2){read(num1);read(num2);} inline void read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){read(num1);read(num2);read(num3);} inline void read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){read(num1);read(num2);read(num3);read(num4);} ll num[maxn],p[maxn]; ll inv=(mod+1)/2; void init(){ num[0]=p[0]=1; rep(i,1,63){ num[i]=num[i-1]*2ll+1ll; p[i]=p[i-1]*2ll; } } ll cal(ll pos){ ll sum=0; for(ll i=1;i<=pos;i*=2ll){ ll num=(pos-i)/(2*i); ll m=i+num*(2ll*i);; num=(num+1ll)%mod; m=(m+i)%mod; m=m*num%mod; m=m*inv%mod; m=m*(__builtin_ctz(i)+1ll)%mod; sum=(sum+m)%mod; } return (sum+1)%mod; } int main(){ //#define test #ifdef test freopen("in.txt","r",stdin);freopen("out.txt","w",stdout); #endif read(casn); init(); while(casn--){ read(n); n--; if(!n){ puts("1"); continue; } ll tmp=n; ll pos=0; for(int i=62;i>=0;i--){ if(tmp>=num[i]){ tmp-=num[i]; pos+=p[i]; } } ll sum=cal(pos); if(tmp){ sum=(sum+tmp%mod*(pos+1ll)%mod)%mod; } printf("%lld\n",sum); } #ifdef test fclose(stdin);fclose(stdout);system("out.txt"); #endif return 0; }
H 組合數學+笛卡爾樹性質
笛卡爾樹的2個重要性質,
1.中序遍歷等於原序列,換句話說,就是把樹拍扁等價於原數列
2.區間的最大元素,就是表示了這個區間的子樹的根節點
放到這個題裏,就是笛卡爾樹的形狀和題目給的同樣,問你多少種...
組合數學,dfs笛卡爾樹記算總種類數,過程當中須要求逆元...
代碼裏的這個笛卡爾樹和線性推逆元是學的dls..
推導參考出題大爺:
#include <bits/stdc++.h> #define ll long long #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(ii,a,b) for(int ii=a;ii<=b;ii++) using namespace std; const int maxn=1e6+10; const int maxm=1e6+10; const int INF=0x3f3f3f3f; const ll mod=1e9+7; #define tpyeinput int inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;} inline void read(tpyeinput &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();} inline void read(tpyeinput &num1,tpyeinput &num2){read(num1);read(num2);} inline void read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){read(num1);read(num2);read(num3);} inline void read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){read(num1);read(num2);read(num3);read(num4);} int casn,n,m,k; struct node{int l,r;}ctree[maxn]; ll inv[maxn],ans; int stk[maxn],vis[maxn]; pair<int,int> num[maxn]; #define nd ctree[now] int dfs(int now){ if(now==0)return 0; int sum=dfs(nd.l)+dfs(nd.r)+1; ans=ans*inv[sum]%mod; // cout<<ans<<endl; return sum; } void maketree(){ int top=0; rep(i,1,n){ int now=top; while(now&&num[stk[now-1]]>num[i]) now--; if(now) ctree[stk[now-1]].r=i; if(now<top) ctree[i].l=stk[now]; stk[now++]=i; top=now; } } int main(){ //#define test #ifdef test freopen("in.txt","r",stdin);freopen("out.txt","w",stdout); #endif inv[1]=1; rep(i,2,maxn-5)inv[i]=inv[mod%i]*(mod-mod/i)%mod; read(casn); while(casn--){ read(n); rep(i,1,n){ int x; read(x); num[i]=make_pair(-x,i); } ans=inv[2]*(ll)n%mod; // cout<<ans<<endl; rep(i,1,n) ctree[i]=(node){0,0},vis[i]=0; maketree(); rep(i,1,n) vis[ctree[i].l]=vis[ctree[i].r]=1; int rt=0; rep(i,1,n) if(vis[i]==0) { rt=i;break; } dfs(rt); printf("%lld\n",ans); } #ifdef test fclose(stdin);fclose(stdout);system("out.txt"); #endif return 0; }
K 模擬題
難點有2個
輸入,偏差..
輸入建議用"scanf("%d %d UTC%c%lf",&h,&m,&flag,&utc);";
也能夠"cin>>h>>m>>ch>>ch>>ch>>ch>>utc";
偏差就是$1.4$會被讀入爲$1.39999$取整變成$1.3$之類的
utc+=0.001就好了,消除偏差,並且不影響答案
#include <bits/stdc++.h> #define ll long long #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(ii,a,b) for(int ii=a;ii<=b;ii++) using namespace std; const int maxn=1e5+10; const int maxm=1e6+10; const int INF=0x3f3f3f3f; int casn,n,m,k; int main(){ //#define test #ifdef test freopen("in.txt","r",stdin);freopen("out.txt","w",stdout); #endif scanf("%d",&casn); int h,m,flag,ch,x; double y; while(casn--){ y=0; double tt; scanf("%d %d UTC%c%lf",&h,&m,&flag,&tt); tt+=0.0001; x=(int)tt; y=tt-x; y*=10; if(flag=='-') { x=-(x+8); y=-y;} else x-=8; int t1=x; int t2=y*6; h+=t1; m+=t2; if(m>=60){ m-=60; h++; } if(h>=24) h-=24; if(m<0){ m+=60; h--; }if(h<0){ h+=24; } printf("%02d:%02d\n",h,m); } #ifdef test fclose(stdin);fclose(stdout);system("out.txt"); #endif return 0; }