The start of the new academic year brought about the problem of accommodation students into dormitories. One of such dormitories has a a × b square meter wonder room. The caretaker wants to accommodate exactly n students there. But the law says that there must be at least 6 square meters per student in a room (that is, the room for n students must have the area of at least 6n square meters). The caretaker can enlarge any (possibly both) side of the room by an arbitrary positive integer of meters. Help him change the room so as all n students could live in it and the total area of the room was as small as possible.
The first line contains three space-separated integers n, a and b (1 ≤ n, a, b ≤ 109) — the number of students and the sizes of the room.
Print three integers s, a1 and b1 (a ≤ a1; b ≤ b1) — the final area of the room and its sizes. If there are multiple optimal solutions, print any of them.
3 3 5
18 3 6
2 4 4
16 4 4
题意:找到两个a,b,比给出的大,并且乘积大于6*n,并且乘积尽量小
思路:枚举1~sqrt(n),然后算出另外的数,看是不是符合条件
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const long long INF=1000000000000000100;
typedef long long LL;
long long n,a,b;
int main()
{
cin>>n>>a>>b;
if(a*b>=6*n){cout<<a*b<<endl<<a<<" "<<b<<endl;return 0;}
n*=6;
bool flag=0;
if(a>b) swap(a, b), flag=1;
LL ans=INF,xx,yy;
for(long long i=1; i<=n; ++i) {
long long x=i, y=(n+x-1)/x;
if(x>y) break;
if(x<a) x=a;
if(y<b) y=b;
if(x*y<ans) {
ans=x*y, xx=x, yy=y;
}
}
if(flag) swap(xx, yy);
printf("%I64d\n%I64d %I64d\n", ans, xx, yy);
return 0;
}
You've got array a[1], a[2], ..., a[n], consisting of n integers. Count the number of ways to split all the elements of the array into three contiguous parts so that the sum of elements in each part is the same.
More formally, you need to find the number of such pairs of indices i, j (2 ≤ i ≤ j ≤ n - 1), that .
The first line contains integer n (1 ≤ n ≤ 5·105), showing how many numbers are in the array. The second line contains n integers a[1], a[2], ..., a[n] (|a[i]| ≤ 109) — the elements of array a.
Print a single integer — the number of ways to split the array into three parts with the same sum.
5 1 2 3 0 3
2
4 0 1 -1 0
1
2 4 1
0
注意long long
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=500010;
typedef long long LL;
int a[maxn],n;
LL sum[maxn];
LL cnt[maxn];
int main()
{
scanf("%d",&n);
LL add=0;
memset(sum,0,sizeof(sum));
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
add+=a[i];
sum[i]=sum[i-1]+a[i];
}
if(add%3){printf("0\n");return 0;}
cnt[n]=(sum[n]-sum[n-1]==add/3?1:0);
for(int i=n-1;i>=1;i--)
{
if(sum[n]-sum[i-1]==add/3)cnt[i]=cnt[i+1]+1;
else cnt[i]=cnt[i+1];
}
LL ans=0;
for(int i=1;i<=n;i++)
{
if(sum[i]==add/3)
ans+=cnt[i+2];
}
cout<<ans<<endl;
return 0;
}
Peter has a sequence of integers a1, a2, ..., an. Peter wants all numbers in the sequence to equal h. He can perform the operation of "adding one on the segment [l, r]": add one to all elements of the sequence with indices from l to r (inclusive). At that, Peter never chooses any element as the beginning of the segment twice. Similarly, Peter never chooses any element as the end of the segment twice. In other words, for any two segments [l1, r1] and [l2, r2], where Peter added one, the following inequalities hold: l1 ≠ l2 and r1 ≠ r2.
How many distinct ways are there to make all numbers in the sequence equal h? Print this number of ways modulo 1000000007 (109 + 7). Two ways are considered distinct if one of them has a segment that isn't in the other way.
The first line contains two integers n, h (1 ≤ n, h ≤ 2000). The next line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 2000).
Print a single integer — the answer to the problem modulo 1000000007 (109 + 7).
3 2 1 1 1
4
5 1 1 1 1 1 1
1
4 3 3 2 1 1
0
思路(转载):
先把a数组变成需要加多少变成h。
然后在对a数组前向差分得出b数组。
cnt:标记到当前位置,有几个l没有和r匹配
如果b[i]==1:
说明当前位置有一个l,cnt++;
如果b[i]==0:
1,当前位置什么都没有
2,当前位置有一个l,一个r。
因为有一个l,所以cnt++.
有一个r,所以总数*=cnt,cnt--;
相当于总数*=(cnt+1);
如果b[i]==-1:
当前位置有一个r,所以总数*=cnt,cnt--;
如果b[i]不等于上面的三种情况,说明无解!
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<stack>
#include<map>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define maxn 550000
#define mod 1000000007
#define LL __int64
LL a[maxn];
LL b[maxn];
int main()
{
int n,h;
while(~scanf("%d%d",&n,&h))
{
for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
for(int i=1;i<=n;i++)a[i]=h-a[i];
for(int i=1;i<=n+1;i++)
{
b[i]=a[i]-a[i-1];
}
LL ans=1;
LL cnt=0;
for(int i=1;i<=n+1;i++)
{
if(b[i]==1)
{
cnt++;
}
else if(b[i]==-1)
{
ans=ans*(cnt)%mod;
cnt--;
}
else if(b[i]==0)
{
ans=ans*(cnt+1)%mod;
}
else
{
ans=0;break;
}
ans=ans%mod;
}
cout<<ans<<endl;
}
return 0;
}
There are n employees working in company "X" (let's number them from 1 to n for convenience). Initially the employees didn't have any relationships among each other. On each of m next days one of the following events took place:
- either employee y became the boss of employee x (at that, employee x didn't have a boss before);
- or employee x gets a packet of documents and signs them; then he gives the packet to his boss. The boss signs the documents and gives them to his boss and so on (the last person to sign the documents sends them to the archive);
- or comes a request of type "determine whether employee x signs certain documents".
Your task is to write a program that will, given the events, answer the queries of the described type. At that, it is guaranteed that throughout the whole working time the company didn't have cyclic dependencies.
The first line contains two integers n and m (1 ≤ n, m ≤ 105) — the number of employees and the number of events.
Each of the next m lines contains the description of one event (the events are given in the chronological order). The first number of the line determines the type of event t (1 ≤ t ≤ 3).
- If t = 1, then next follow two integers x and y (1 ≤ x, y ≤ n) — numbers of the company employees. It is guaranteed that employee x doesn't have the boss currently.
- If t = 2, then next follow integer x (1 ≤ x ≤ n) — the number of the employee who got a document packet.
- If t = 3, then next follow two integers x and i (1 ≤ x ≤ n; 1 ≤ i ≤ [number of packets that have already been given]) — the employee and the number of the document packet for which you need to find out information. The document packets are numbered started from 1 in the chronological order.
It is guaranteed that the input has at least one query of the third type.
For each query of the third type print "YES" if the employee signed the document package and "NO" otherwise. Print all the words without the quotes.
4 9 1 4 3 2 4 3 3 1 1 2 3 2 2 3 1 2 1 3 1 2 2 3 1 3
YES NO YES
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=100010;
int N,M,pra[maxn],num[maxn];
bool vis[maxn];
vector<int> g[maxn];
vector<pair<int,int> > q[maxn];
vector<pair<int,int> > file;
int find(int x)
{
if(pra[x]==x)return x;
return pra[x]=find(pra[x]);
}
void dfs(int u)
{
vis[u]=1;
int len=g[u].size();
for(int i=0;i<len;i++)
dfs(g[u][i]);
len=q[u].size();
for(int i=0;i<len;i++)
{
if(vis[q[u][i].first])
num[q[u][i].second]++;
}
vis[u]=0;
}
int main()
{
scanf("%d%d",&N,&M);
for(int i=1;i<=N;i++)pra[i]=i;
int cnt=0;
for(int i=1;i<=M;i++)
{
int t,x,y;
scanf("%d%d",&t,&x);
if(t==1)
{
scanf("%d",&y);
g[y].push_back(x);
int px=find(x),py=find(y);
if(px!=py)pra[px]=py;
}
else if(t==2)
{
file.push_back(make_pair(find(x),x));
}
else if(t==3)
{
scanf("%d",&y);
q[x].push_back(make_pair(file[y-1].first,cnt));
q[file[y-1].second].push_back(make_pair(x,cnt));
cnt++;
}
}
memset(vis,0,sizeof(vis));
memset(num,0,sizeof(num));
for(int i=1;i<=N;i++)
if(pra[i]==i)dfs(i);
for(int i=0;i<cnt;i++)
if(num[i]==2)printf("YES\n");
else printf("NO\n");
return 0;
}