標籤:
題目1 : 打折機票時間限制:10000ms單點時限:1000ms記憶體限制:256MB
描述
因為思念新宿的"小姐姐"們,島娘計劃6月份再去一趟東京,不過這次看來她需要自掏腰包。經過了幾天的夜戰,島娘終於在體力耗盡之前,用Python抓下了所有6月份,上海至東京的全部共 n 張機票。現在請你協助債台高築的島娘篩選出符合時間區間要求的,最貴的機票。
輸入
輸入資料的第一行包含兩個整數 n,?m(1?≤?n,?m?≤?105),分別表示機票的總數,和詢問的總數。接下來的 n 行,每行兩個整數 t,?v (1?≤?t,?v?≤?105),表示每張機票出發的時間和價格。 接下來的 m 行,每行兩個整數 a,?b (1?≤?a?≤?b?≤?105),表示每個詢問所要求的時間區間。
輸出
對於每組詢問,輸出一行表示最貴的價格。如果沒有符合要求的機票,輸出一行"None"。
-
範例輸入
-
7 61 12 14 34 44 56 97 91 71 26 73 34 45 5
-
範例輸出
-
919None5None
解題思路:純線段樹模板題,求區間最大值
題目連結→1299 打折機票
#pragma comment(linker, "/STACK:1024000000,1024000000")#include<stdio.h>#include<string.h>#include<stdlib.h>#include<queue>#include<stack>#include<math.h>#include<vector>#include<map>#include<set>#include<cmath>#include<string>#include<algorithm>#include<iostream>#define exp 1e-4using namespace std;const int N = 100005;const int M = 100000;const int inf = 100000;const int mod = 2009;struct tree{ int left,right,Max;}s[4*N];int a[N];void buildtree(int l,int r,int p){ s[p].left=l,s[p].right=r; if(l==r) { s[p].Max=a[l]; return ; } int mid=(l+r)/2; buildtree(l,mid,p*2); buildtree(mid+1,r,p*2+1); s[p].Max=max(s[p*2].Max,s[p*2+1].Max);}int search(int l,int r,int p){ if(l<=s[p].left&&s[p].right<=r) return s[p].Max; int mid=(s[p].left+s[p].right)/2; if(l>mid) return search(l,r,p*2+1); else if(r<=mid) return search(l,r,p*2); else return max(search(l,mid,p*2),search(mid+1,r,p*2+1));}int main(){ int n,m,i,t,v,l,r,ans; while(~scanf("%d%d",&n,&m)) { memset(a,0,sizeof(a)); for(i=1;i<=n;i++) { scanf("%d%d",&t,&v); a[t]=max(a[t],v); } buildtree(1,n,1); for(i=0;i<m;i++) { scanf("%d%d",&l,&r); ans=search(l,r,1); if(!ans) puts("None"); else printf("%d\n",ans); } } return 0;}
題目2 : 展勝地的鯉魚旗時間限制:10000ms單點時限:1000ms記憶體限制:256MB
描述
岩手縣北上市的「北上市立公園展勝地」,是陸奧國三大櫻花名所之一。每年的四月中旬到五月初,這裡都會舉辦盛大的祭奠。除了可以在盛開的櫻花步道上乘坐觀光馬車徐行、還有橫跨北上川上的鯉魚旗,河畔還有當地特有的為祭奠祖先而編創的北上鬼劍舞。
假設,我們用一個包含 ‘(‘, ‘)‘的括弧字串來區別每面鯉魚旗的方向。一段括弧序列被稱為合法的,若且唯若滿足兩個條件:一、對於整個序列,左括弧數量等於右括弧;二、對於任意首碼,左括弧的數目都不小於右括弧的數目。島娘想知道,對於一串括弧字串,有多少子串是合法的,你能協助她麼。
輸入
輸入資料僅一行,包含一個長度為 n (1?≤?n?≤?106) 的括弧字串。
輸出
輸出一行,表示合法的括弧子串的數目。
-
範例輸入
-
(()())
-
範例輸出
-
4
解題思路:括弧匹配問題,不過找的是合法的子串數目
首先,我們來整理一下如何求合法的子串數目
對於(()()(()))(),其實可以把各種括弧進行分層
(( ) ( )(( ))) ( )
0 1 1 1 1 1 2 2 1 0 0 0
相同層的用等差數列求和就能算得當層的合法子串數
而需要特別處理的是多餘的右括弧,即沒有左括弧能與之匹配的右括弧,對於這些右括弧,統一分成-1組,不對其做處理即可
如:
) ) ) ) ( ( ) ( ) )
-1 -1 -1 -1 0 1 1 1 1 0
題目連結→1300 展勝地的鯉魚旗
#pragma comment(linker, "/STACK:1024000000,1024000000")#include<stdio.h>#include<string.h>#include<stdlib.h>#include<queue>#include<stack>#include<math.h>#include<vector>#include<map>#include<set>#include<cmath>#include<string>#include<algorithm>#include<iostream>#define exp 1e-4using namespace std;const int N = 1000005;const int M = 100000;const int inf = 100000;const int mod = 2009;char s[N];stack<char> p;stack<int> m;int ans[N],q[N];int main(){ int i,k,c; while(~scanf("%s",s)) { c=k=0; while(!p.empty())p.pop();while(!m.empty())m.pop();for(i=0;s[i]!='\0';i++)if(s[i]=='('){if(m.empty())m.push(0);elsem.push(m.top()+1);q[k++]=m.top();p.push('(');}else{if(!p.empty()&&p.top()=='('){q[k++]=m.top();p.pop();m.pop();}else{p.push(')');q[k++]=-1;}}/*for(i=0;i<k;i++)printf("%d ",q[i]);puts("");*/memset(ans,0,sizeof(ans));ans[q[0]]++;for(i=1;i<k;i++){if(q[i]<q[i-1]){if(q[i-1]!=-1){ans[q[i-1]]/=2;c+=ans[q[i-1]]*(ans[q[i-1]]+1)/2;ans[q[i-1]]=0;}}ans[q[i]]++;//printf("%d %d\n",i,c);}if(q[i-1]!=-1){ans[q[i-1]]/=2;c+=ans[q[i-1]]*(ans[q[i-1]]+1)/2;ans[q[i-1]]=0;//printf("#c=%d\n",c);}for(i=q[i-1]-1;i>=0;i--){ans[i]/=2;c+=ans[i]*(ans[i]+1)/2;ans[i]=0;//printf("@c=%d\n",c);}printf("%d\n",c); } return 0;}/*()()(())())(())()))(((()))(()*/
菜鳥成長記
hihoCoder挑戰賽20