
因为思念新宿的"小姐姐"们,岛娘计划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 6 1 1 2 1 4 3 4 4 4 5 6 9 7 9 1 7 1 2 6 7 3 3 4 4 5 5
9 1 9 None 5 None
题目链接→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-4
using 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;
}
岩手县北上市的「北上市立公园展胜地」,是陆奥国三大樱花名所之一。每年的四月中旬到五月初,这里都会举办盛大的祭奠。除了可以在盛开的樱花步道上乘坐观光马车徐行、还有横跨北上川上的鲤鱼旗,河畔还有当地特有的为祭奠祖先而编创的北上鬼剑舞。

假设,我们用一个包含 ‘(‘, ‘)‘的括号字符串来区别每面鲤鱼旗的方向。一段括号序列被称为合法的,当且仅当满足两个条件:一、对于整个序列,左括号数量等于右括号;二、对于任意前缀,左括号的数目都不小于右括号的数目。岛娘想知道,对于一串括号字符串,有多少子串是合法的,你能帮助她么。
输入数据仅一行,包含一个长度为 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-4
using 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);
else
m.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;
}
/*
()()(())())
(())()))(((()))(()
*/
菜鸟成长记
原文:http://blog.csdn.net/queuelovestack/article/details/51334609