A Apple Pie
#include
using namespace std;
int a,b;
int main()
{
cin>>a>>b;
cout<<(a*3+b)/2<
B Guidebook
#include
using namespace std;
int n;
struct node
{
string a;
int b,id;
bool operator<(const node&o)const
{
if(a==o.a) return b>o.b;
return a>p[i].a>>p[i].b;
p[i].id=i;
}
sort(p+1,p+1+n);
for(int i=1;i<=n;i++)
printf("%d\n",p[i].id);
}
C Switches
状态压缩,二进制位1表示这个位置的开关被打开,为0表示被关闭
#include
using namespace std;
int n,m,a[15];
bool vis[15];
vectorv[15];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x;
scanf("%d",&x);
while(x--)
{
int y;
scanf("%d",&y);
v[i].push_back(y);
}
}
for(int i=1;i<=m;i++)
scanf("%d",&a[i]);
int ans=0;
for(int i=0;i<1<
D equeue
数据范围很小,因为每次取可以左右取,只要枚举左边去了多少个,右边去了多少个,把手中的数当然取完后再弹出来事最优的。时间复杂度O(n^2)也过得去,所以就暴力枚举了。无脑开了MAXN=50,WA了一发。
#include
#define ll long long
using namespace std;
int n,k;
ll a[555];
priority_queue,greater >q;
int main()
{
ll ans=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=0;i<=min(n,k);i++)
for(int j=0;i+j<=min(n,k);j++)
{
for(int h=1,t=1;h<=i;h++,t++)
q.push(a[t]);
for(int h=1,t=n;h<=j;h++,t--)
q.push(a[t]);
int p=k-i-j;
while(!q.empty()&&p>0&&q.top()<0)
{
q.pop();
p--;
}
ll res=0;
while(!q.empty())
{
res+=q.top();
q.pop();
}
ans=max(ans,res);
}
printf("%lld\n",ans);
}
E Roadwork
把q个人出发的时间线排序(当然给出的时间线是有序的),推测每个点x会阻挡那一段时间出发的人,不过不能暴力遍历这段时间被哪些点阻挡,但可以在有序的时间段内找出一个l,r位置,在按顺序遍历q个人时,如果碰到x的l位置,则把x插入集合,碰到r位置,则把x从集合中删除,因为较小的x一定会先阻挡某个人,所以答案是集合中最小的数,如果集合中没有这样的数,答案就是-1,又因为一个位置可以是多个x的l位置或者多个x的r位置,因此我这里用队列维护了一个多个集合。
PS:一开始把队列开在了结构体里,然后每次运行的时间stl就莫名的会让程序卡很久,就莫名的T了几发。
#include
using namespace std;
const int N=2e5+5;
int n,q,b[N],ans[N];
int flag,t[4*N],hs[N];
queueqa[N],qb[N];
struct node
{
int s,t,x;
}a[N];
bool cmp(node a,node b)
{
return a.x>1;
if(x<=m) fix(l,m,k<<1,x);
else fix(m+1,r,k<<1|1,x);
t[k]=t[k<<1]+t[k<<1|1];
}
void del(int l,int r,int k,int x)
{
if(l==r)
{
t[k]--;
if(l==flag) flag=0;
return;
}
int m=l+r>>1;
if(x<=m) del(l,m,k<<1,x);
else del(m+1,r,k<<1|1,x);
t[k]=t[k<<1]+t[k<<1|1];
}
int query(int l,int r,int k)
{
if(l==r) return hs[l];
int m=l+r>>1;
if(t[k<<1]) return query(l,m,k<<1);
else if(t[k<<1|1]) return query(m+1,r,k<<1|1);
return -1;
}
int read()
{
char c=getchar();int x=0,f=1;
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
if(c=='-') f=-1,c=getchar();
while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=getchar();
return x*f;
}
int main()
{
n=read();q=read();
for(int i=1;i<=n;i++)
a[i].s=read(),a[i].t=read(),a[i].x=read(),hs[i]=a[i].x;
sort(hs+1,hs+1+n);
sort(a+1,a+1+n,cmp);
for(int i=1;i<=q;i++)
b[i]=read();
for(int i=n;i>=1;i--)
{
int s=a[i].s,t=a[i].t;
int l=lower_bound(b+1,b+1+q,s-a[i].x)-b,r=lower_bound(b+1,b+1+q,t-a[i].x)-b-1;
if(l>r) continue;
qa[l].push(i);
qb[r].push(i);
}
for(int i=1;i<=q;i++)
{
while(!qa[i].empty())
{
fix(1,n,1,qa[i].front());
qa[i].pop();
}
if(!flag)
ans[i]=query(1,n,1);
else ans[i]=hs[flag];
while(!qb[i].empty())
{
del(1,n,1,qb[i].front());
qb[i].pop();
}
}
for(int i=1;i<=q;i++)
printf("%d\n",ans[i]);
}
F Frog Jump
任取个a,b,把遍历的位置列一下a,a-b,2*a-b,2*a-2*b…x*a-(x-1)*b,就有x*a-(x-1)*b=n-1。设p=a-b,则b=a-p,就有x*a-(x-1)*(a-p)=n-1,于是又(n-1-a)%p=0,因为p是(n-1-a)的因子,而相对于1e5的数据,因子的个数就比较少了。枚举一下a,再考虑枚举(n-1-a)所有的因子,我这里用数论分块logn进行枚举。当然枚举了p,也不能暴力去计算答案呀,因此再用前缀和和后缀和分块进行一下预处理,当p<=sqrt(n)时,可以O(1)从前缀后缀和中得出答案,当p>sqrt(n)就算暴力去跑,时间消耗也很小了。
当然,还没有结束,因为还要考虑怎么避开选择的a,b会使得跳的时候不会出现重合的情况,在图上画一下,发现可以把这个过程分解成两个部分,一个是从a,一直加p(p=a-b)直到n-1的位置,一个是从n-1-a位置开始,一直减b,直到0的位置结束,期间只要保持两个部分不相交就行了,设x=a,y=n-1-a,当x>y的时候,显然不会相交,当x=y显然已经相交了,当x
#include
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,a[N];
ll pre[322][N],bk[322][N];
sets;
void solve()
{
ll ans=0;
for(int x=1;x=0;k-=x-y)
{
if(s.count(k)) {res=0;break;}
res+=a[k];
}
s.clear();
ans=max(ans,res);
}
printf("%lld\n",ans);
}
int main()
{
scanf("%d",&n);
for(int i=0;i=0;j-=i)
bk[i][j]=a[j];
for(int j=n-1-i;j>=0;j--)
bk[i][j]+=bk[i][j+1];
}
for(int i=1;iy) break;
r=y/(y/l);
}
}
else if(s>0)
{
int l=1,r=1;
while(l<=y)
{
if(y%l==0&&s%l!=0&&ly) break;
r=y/(y/l);
}
}
}
printf("%lld\n",ans);
}
/*
a=6,b=4
11
0 -4 0 -99 31 14 -15 -39 43 18 0
*/