There are consecutive buildings numbered from 1 to 109 each of which has an amount of money in it. The money is given in the form of mnon-overlapping segments, in which each segment i has 3 values: li, ri, and vi, meaning that each building with number x (li ≤ x ≤ ri) has vi amount of money.
A thief came to rob the city, however, this thief does not want to get caught, so he can only rob at most k consecutive buildings, such that if he starts robbing buildings from building z, he can rob all buildings in the range inclusive.
Your task is to find the maximum amount of money the thief can collect. Can you?
The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.
The first line of each test case contains two integers m and k (1 ≤ m ≤ 1e5, 1 ≤ k ≤ 1e9), in which m is the number money segments, and k is the maximum number of consecutive buildings the thief can rob.
Then m lines follow, giving the description of money segments. Each segment i is represented by 3 integers li, ri and vi (1 ≤ li ≤ ri ≤ 1e9, 1 ≤ vi ≤ 1e9), in which li and ri are the boundaries of the segment, and vi is the amount of money in each building in that segment.
The sum of m overall test cases does not exceed 2 × 1e6.
For each test case, print a single line containing the maximum amount of money the thief can collect by robbing at most k consecutive buildings.
1
2 5
1 5 1
7 11 1
5
题意:数轴上有1e9个点,有n(1e5)个区间,每个区间内所有点有一个相同的值ai,你可以从任意一个点开始取连续的k个数,求最大总值。
题解:易知,总值最大时的取法一定是起点在某个区间的起点或者终点在某个区间的终点(因为如果不这样取,总可以通过向左或向右移动得到更优的解),而区间的个数是1e5的数量级,所以可以直接枚举区间起点利用二分找到相应终点求出一个最优解,再通过直接枚举区间终点利用二分找到相应起点来求出另一个最优解,取二者最小值即可。
注意一些细节即可。(使用lowerbound和upperbound时注意数组边界)
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<map> 5 #include<cstdio> 6 #include<algorithm> 7 using namespace std; 8 typedef long long ll; 9 struct edge{ 10 ll l; 11 ll r; 12 ll val; 13 }e[100005]; 14 ll sum[100005]; 15 ll id[100005],id2[100005]; 16 bool cmp(struct edge aa,struct edge bb){ 17 return aa.l<bb.l; 18 } 19 int main(){ 20 int t; 21 scanf("%d",&t); 22 while(t--){ 23 ll m,k; 24 scanf("%lld%lld",&m,&k); 25 for(int i=1;i<=m;i++)scanf("%lld%lld%lld",&e[i].l,&e[i].r,&e[i].val); 26 sort(e+1,e+1+m,cmp); 27 for(int i=1;i<=m;i++){ 28 sum[i]=sum[i-1]+e[i].val*(e[i].r-e[i].l+1); 29 id[i]=e[i].r; 30 id2[m-i+1]=-e[i].l; 31 } 32 /* 33 1 34 2 5 35 1 4 2 36 6 7 1 37 */ 38 ll ans=0; 39 for(int i=1;i<=m;i++){ 40 int xx=lower_bound(id+1,id+1+m,e[i].l+k-1)-id; 41 //cout<<xx<<endl; 42 ll s=sum[xx-1]-sum[i-1]; 43 if(xx<=m)s+=(max(0ll,min(e[i].l+k-1,id[xx])-e[xx].l+1))*e[xx].val; 44 ans=max(s,ans); 45 } 46 for(int i=m;i>=1;i--){ 47 int xx=lower_bound(id2+1,id2+1+m,-e[i].r+k-1)-id2; 48 ll s=sum[i]-sum[m-(xx-1)]; 49 if(xx<=m)s+=max(0ll,(min(-e[i].r+k-1,id2[xx])-(-e[m-xx+1].r)+1))*e[m-xx+1].val; 50 ans=max(s,ans); 51 } 52 printf("%lld ",ans); 53 } 54 return 0; 55 }
Abood's birthday has come, and his n friends are aligned in a single line from 1 to n, waiting for their cookies, Abood has x cookies to give to his friends.
Here is an example to understand how Abood gives away the cookies. Suppose Abood has 4 friends and x cookies, then Abood will do the following:
- Give a cookie to the 1st friend.
- Give a cookie to the 2nd friend.
- Give a cookie to the 3rd friend.
- Give a cookie to the 4th friend.
- Give a cookie to the 3rd friend.
- Give a cookie to the 2nd friend.
- Give a cookie to the 1st friend.
- Give a cookie to the 2nd friend.
- And so on until all the x cookies are given away.
Your task is to find how many cookies each friend will get. Can you?
The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.
Each test case consists of a single line containing two integers x and n (1 ≤ x ≤ 1e18, 1 ≤ n ≤ 1000), in which x is the number of cookies Abood has, and n is the number of his friends.
For each test case, print a single line containing n space-separated integers a1, ..., an, in which ai represents how many cookies the ithfriend got.
1
5 3
2 2 1
题意:按题目要求分饼干。
题解:按要求模拟即可
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<map> 5 #include<cstdio> 6 #include<algorithm> 7 using namespace std; 8 typedef long long ll; 9 ll a[1005]; 10 int main(){ 11 int t; 12 scanf("%d",&t); 13 while(t--){ 14 ll x,n; 15 scanf("%lld%lld",&x,&n); 16 if(n==1){ 17 printf("%lld ",x); 18 } 19 else{if(x<=n){ 20 for(int i=1;i<=n;i++){ 21 int s=(i<=x); 22 printf("%d",s); 23 char cc=(i==n)?' ':' '; 24 printf("%c",cc); 25 } 26 } 27 else{ 28 x-=n; 29 ll q=x/(n-1); 30 if(q%2){ 31 a[1]=((q+1)/2)+1; 32 a[n]=(q/2)+1; 33 for(int i=2;i<=1+x%(n-1);i++){ 34 a[i]=q+2; 35 } 36 for(int i=2+x%(n-1);i<=n-1;i++){ 37 a[i]=q+1; 38 } 39 } 40 else{ 41 a[1]=((q)/2)+1; 42 a[n]=(q/2)+1; 43 for(int i=n-1;i>=n-x%(n-1);i--){ 44 a[i]=q+2; 45 } 46 for(int i=n-x%(n-1)-1;i>=2;i--){ 47 a[i]=q+1; 48 } 49 } 50 for(int i=1;i<=n;i++){ 51 printf("%lld",a[i]); 52 char cc=(i==n)?' ':' '; 53 printf("%c",cc); 54 } 55 } 56 } 57 } 58 return 0; 59 }
You are given a positive integer n. Your task is to build a number m by flipping the minimum number of bits in the binary representation of nsuch that m is less than n (m < n) and it is as maximal as possible. Can you?
The first line contains an integer T (1 ≤ T ≤ 1e5) specifying the number of test cases.
Each test case consists of a single line containing one integer n (1 ≤ n ≤ 1e9), as described in the statement above.
For each test case, print a single line containing the minimum number of bits you need to flip in the binary representation of n to build the number m.
2
5
10
1
2
题意:求x与x-1二进制下的不同数位的个数。
题解:异或之后直接求即可
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<map> 5 #include<cstdio> 6 #include<algorithm> 7 using namespace std; 8 typedef long long ll; 9 ll a[1005]; 10 int main(){ 11 int t; 12 scanf("%d",&t); 13 while(t--){ 14 int n; 15 scanf("%d",&n); 16 int k=(n-1)^n; 17 int ans=0; 18 while(k){ 19 if(k&1)ans++; 20 k/=2; 21 } 22 printf("%d ",ans); 23 } 24 return 0; 25 }
You are given a n × m grid, your goal is to find a group of lines such that the following conditions are met:
- No two lines are touching.
- Each cell in the grid has one of its sides covered by at least one line in the group.
A line is a border of a cell in the grid with length 1. Each cell has 4 lines covering every side of it. Every pair of neighboring cells shares a line. Two lines are touching if they meet at their ends.
The size of a group of lines is the number of lines it contains. Your task is to find the minimum size of a group of lines that meet all the conditions above. Can you?
The first line contains an integer T (1 ≤ T ≤ 128) specifying the number of test cases.
Each test case consists of a single line containing two integers n and m (1 ≤ n ≤ 1e9, 1 ≤ m ≤ 1024), giving a grid of size n × m.
For each test case, print a single line containing the minimum size of a group of lines that meet all the conditions in the statement above.
1
4 4
10
题意:一个n*m的矩形,里面一共有n*m个格子,要求每个格子至少一条边被标记,并且所有被标记的边不能相交,求最少要标记多少边。
题解:这个我完全是画出样例的情形图之后猜公式..
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<map> 5 #include<cstdio> 6 #include<algorithm> 7 using namespace std; 8 typedef long long ll; 9 const int mod=1e9+7; 10 ll n,m; 11 ll sol(ll n,ll m){ 12 return n*((m+1)/2)+((m+1)%2)*((n)/2); 13 } 14 int main(){ 15 int t; 16 scanf("%d",&t); 17 while(t--){ 18 scanf("%lld%lld",&n,&m); 19 20 ll xx=min(sol(n,m),sol(m,n)); 21 printf("%lld ",xx); 22 23 } 24 return 0; 25 }
You are given an n-dimensional grid in which the dimensions of the grid are a1 × a2 × ... × an. Each cell in the grid is represented as an n-tuple (x1, x2, ..., xn) (1 ≤ xi ≤ ai).
Two cells are considered to be adjacent if the Manhattan Distance between them is equal to 1. The Manhattan Distancebetween two cells X(x1, x2, ..., xn) and Y(y1, y2, ..., yn) is equal to: |x1 - y1| + |x2 - y2| + ... + |xn - yn|.
Your task is to count how many pairs of cells are adjacents. Can you? Two pairs of cells are considered the same if they include the same cells, i.e the pair (c1, c2) is the same as (c2, c1).
The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.
The first line of each test case contains an integer n (1 ≤ n ≤ 1e5), in which n is the number of dimensions of the grid. Then a line follows containing n integers a1, ..., an (1 ≤ ai ≤ 1e5), in which ai is the size of the ith dimension.
The sum of n overall test cases does not exceed 6 × 1e6.
For each test case, print a single line containing the number of pairs of adjacent cells modulo 1e9 + 7.
1
3
1 2 3
7
The absolute value |x| of a real number x is the non-negative value of x without regard to its sign. Namely, |x| = x for a positive x, |x| = - xfor a negative x (in which case - x is positive), and |0| = 0. For example, the absolute value of 3 is 3, and the absolute value of - 3 is also 3. The absolute value of a number may be thought of as its distance from zero.
题意:一共n个数列,每个数列中都有ai个值,分别为1,2,3...ai,在每个数列中选两个值分别放到两个队列中,则最后两个队列中各有n个值,要求最后两个队列的对应元素相减的绝对值之和=1,求总情况数%1e9+7.
题解:由于绝对值之和的最后结果需要=1,所以只能是两个队列某个位置的差值为1(每个数列有ai-1种情况),其他对应元素值为0(每个数列有ai种情况),所以共有$sum_{i=1}^n$(($sum_{j=1}^n$aj)/ai*(ai-1))种方案,求解过程可以先计算出($sum_{j=1}^n$aj)%mod,然后*mypow(aj,mod-2)求出结果,注意这题会卡常..用long long会超时,改成int就过了
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<map> 5 #include<cstdio> 6 #include<algorithm> 7 using namespace std; 8 typedef long long ll; 9 const int mod=1e9+7; 10 int a[100005],in[100005]; 11 ll mypow(ll x,int y){ 12 ll ans=1; 13 while(y){ 14 if(y&1)ans=ans*x%mod; 15 x=x*x%mod; 16 y/=2; 17 } 18 return ans; 19 } 20 int main(){ 21 int t; 22 scanf("%d",&t); 23 while(t--){ 24 int n; 25 scanf("%d",&n); 26 ll ak=1; 27 for(int i=1;i<=n;i++){ 28 scanf("%d",&a[i]); 29 in[a[i]]++; 30 ak=ak*a[i]%mod; 31 } 32 ll ans=0; 33 sort(a+1,a+1+n); 34 int k=unique(a+1,a+1+n)-a-1; 35 for(int i=1;i<=k;i++){ 36 ans=(ans+in[a[i]]*(ak*mypow((long long)a[i],mod-2)%mod*(a[i]-1)%mod)%mod)%mod; 37 in[a[i]]=0; 38 } 39 printf("%lld ",ans); 40 } 41 return 0; 42 }
You are given an array a consisting of n integers a1, ..., an. In one operation, you can choose 2 elements ai and aj in which ai is divisible by aj and transform ai to aj.
A number x is said to be divisible by a number y if x can be divided by y and the result is an exact whole number. For example, 15 is divisible by 3, because 15÷ 3 = 5 exactly, but 9 is not divisible by 2 because 9÷ 2 is 4 with 1 left over.
Your task is to find the minimum sum of the array a that can be obtained by making as many transform operations as you want. Can you?
The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.
The first line of each test case contains an integer n (1 ≤ n ≤ 1e5), in which n is the size of array a. Then a line follows containing nintegers a1, ..., an (1 ≤ ai ≤ 1e6), giving array a.
The sum of n overall test cases does not exceed 3 × 1e6.
For each test case, print a single line containing the minimum sum of the array a that can be obtained after making as many transform operations as you want.
1
5
2 2 3 6 6
11
题意:给一个数组,规定如果ai%aj==0,那么可以将ai变成aj,求最后得到的数组的总和最小值
题解:用类似于筛素数的方法,可以在($sum_{i=1}^n$(1/i))*n的复杂度内完成,而($sum_{i=1}^n$(1/i))*n,近似等于nlogn
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<map> 5 #include<cstdio> 6 #include<algorithm> 7 using namespace std; 8 typedef long long ll; 9 ll a[100005],b[1000005],c[100005]; 10 int main(){ 11 int t; 12 scanf("%d",&t); 13 while(t--){ 14 int n; 15 scanf("%d",&n); 16 for(int i=1;i<=n;i++){ 17 scanf("%lld",&a[i]); 18 b[a[i]]=a[i]; 19 c[i]=a[i]; 20 } 21 sort(a+1,a+1+n); 22 int k=unique(a+1,a+1+n)-(a+1); 23 for(int i=1;i<=k;i++){ 24 for(int j=a[i];j<=a[k];j+=a[i]){ 25 if(b[j]==j)b[j]=b[a[i]]; 26 } 27 } 28 ll ans=0; 29 for(int i=1;i<=n;i++){ 30 ans+=b[c[i]]; 31 //cout<<a[i]<<endl; 32 } 33 printf("%lld ",ans); 34 } 35 return 0; 36 }
Ali is trying to make his friends happier by matching them into pairs together. In the beginning, Ali has 2 × n friends standing in a row and numbered from 1 to 2 × n. Each friend i will be matched with the friend numbered (2 × n - i + 1).
Each friend i has a happiness level equal to hi. The happiness level of a matched pair of friends i and (2 × n - i + 1) is equal to hi + h2 × n - i + 1.
Your task is to find the maximum happiness level of a pair among all matched pairs. Can you?
The first line contains an integer T (1 ≤ T ≤ 50) specifying the number of test cases.
The first line of each test case contains an integer n (1 ≤ n ≤ 1000), giving that Ali has 2 × n friends. Then a line follows containing 2 × nintegers h1, ..., h2 × n (1 ≤ hi ≤ 1000), in which hi represents the happiness level of the ith friend.
For each test case, print a single line containing the maximum happiness level of a pair among all matched pairs.
1
3
2 4 5 6 7 8
11
题解:签到
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<map> 5 #include<cstdio> 6 #include<algorithm> 7 using namespace std; 8 typedef long long ll; 9 int a[2005]; 10 int main(){ 11 int t; 12 scanf("%d",&t); 13 while(t--){ 14 int n; 15 int ans=0; 16 scanf("%d",&n); 17 for(int i=1;i<=2*n;i++){ 18 scanf("%d",&a[i]); 19 if(i>n){ 20 ans=max(a[i]+a[2*n-i+1],ans); 21 } 22 } 23 printf("%d ",ans); 24 } 25 return 0; 26 }
You are given an integer x. Your task is to split the number x into exactly n strictly positive integers such that the difference between the largest and smallest integer among them is as minimal as possible. Can you?
The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.
Each test case consists of a single line containing two integers x and n (1 ≤ x ≤ 109, 1 ≤ n ≤ 1000), as described in the statement above.
For each test case, print a single line containing n space-separated integers sorted in a non-decreasing order. If there is no answer, print - 1.
1
5 3
1 2 2
题解:签到
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<map> 5 #include<cstdio> 6 #include<algorithm> 7 using namespace std; 8 typedef long long ll; 9 int a[2005]; 10 int main(){ 11 int t; 12 scanf("%d",&t); 13 while(t--){ 14 int n,x; 15 scanf("%d%d",&x,&n); 16 if(x<n){ 17 printf("-1 "); 18 } 19 else{ 20 int s=x/n; 21 int m=x%n; 22 for(int i=1;i<=n;i++){ 23 int ss=s+(n-i+1<=m); 24 printf("%d",ss); 25 char cc=(i==n)?' ':' '; 26 printf("%c",cc); 27 28 } 29 } 30 } 31 return 0; 32 }
You are given n islands numbered from 1 to n and connected using n - 1 magical bridges. A greedy pirate wants to collect as many coins as possible by traveling through the bridges. Each bridge is a two-way bridge, but the pirate can only use the bridge at most twice. If a bridge connects islands u and v, then going from u to v gives c1 coins, and going from v to u gives c2.
Help the pirate to collect as many coins as he can knowing that he will start from some island x and finish at some island y.
The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.
The first line of each test case contains one integer n (2 ≤ n ≤ 105), in which n is the number of islands. The n - 1 lines follow, giving the bridges. Each line contains four integers u, v, c1, and c2 (1 ≤ u, v ≤ n, 1 ≤ c1, c2 ≤ 104), as describing in the statement above.
The next line contains an integer q (1 ≤ q ≤ 105), in which q is the number of queries. Then q lines follow, giving queries. Each query consists of two integers x and y (1 ≤ x, y ≤ n), in which x and y are the starting and finish islands, respectively.
The sum of n and q overall test cases does not exceed 25 × 105 for each.
For each query, print a single line containing the maximum amount of money the greedy pirate can collect by traveling through the bridges starting from island x and finishing at island y.
1
5
1 2 5 10
3 5 25 3
4 2 15 12
3 2 6 7
2
1 5
4 3
64
65
题意:给一棵树,树边u->v和v->u的权值不一样,每条边最多经过两次,有q次询问,求从u到v走过的权值和的最大值
题解:树上两点的距离关系,可以想到使用LCA求解,因为每条边最多走两次,所以从u到v的路径只能向前移动,而不能后退,所以也就是从u到v的路径只能走一次,所以结果就=所有边的权值和-从v到u的路径权值和,用LCA很容易得到结果
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<map> 5 #include<cstdio> 6 #include<algorithm> 7 #include<vector> 8 using namespace std; 9 typedef long long ll; 10 const int mod=1e9+7; 11 const int maxn=1e5+5; 12 struct edge{ 13 int x; 14 int y; 15 int nex; 16 int v1; 17 int v2; 18 }e[maxn<<1]; 19 int cnt,head[maxn],dis1[maxn],dis2[maxn]; 20 void adde(int x1,int y1,int z1,int c1){ 21 e[cnt].x=x1; 22 e[cnt].y=y1; 23 e[cnt].v1=z1; 24 e[cnt].v2=c1; 25 e[cnt].nex=head[x1]; 26 head[x1]=cnt++; 27 } 28 struct pot{ 29 int xzc; 30 int aq; 31 }; 32 vector<struct pot>query[maxn]; 33 vector<int>num[maxn]; 34 int vis[maxn],ans[maxn],fa[maxn]; 35 void init(int n) 36 { 37 for(int i=1;i<=n;i++){dis1[i]=dis2[i]=0;fa[i]=i;vis[i]=0;num[i].clear();query[i].clear();} 38 } 39 int finds(int x) 40 { 41 int xx=x; 42 while(fa[x]!=x) 43 { 44 x=fa[x]; 45 } 46 while(fa[xx]!=x) 47 { 48 int t=fa[xx]; 49 fa[xx]=x; 50 xx=t; 51 } 52 return x; 53 } 54 void Union(int x,int y) 55 { 56 int xx=finds(x); 57 int yy=finds(y); 58 if(xx!=yy); 59 fa[yy]=xx;//在完成子节点的Tarjan遍历之后,把子节点纳入父节点名下 60 } 61 void Tarjan(int u,int a1,int a2) 62 { 63 vis[u]=1; 64 dis1[u]=a1; 65 dis2[u]=a2; 66 for(int i=head[u] ; i != -1 ;i=e[i].nex) 67 { 68 int v=e[i].y; 69 if(vis[v])continue; 70 Tarjan(v,e[i].v1+a1,e[i].v2+a2); 71 Union(u,v); 72 } 73 for(int i = 0 ; i < query[u].size() ; i++) 74 { 75 if(vis[query[u][i].aq]) 76 { 77 if(query[u][i].xzc) 78 ans[num[u][i]]=dis2[query[u][i].aq]+dis1[u]-dis1[finds(query[u][i].aq)]-dis2[finds(query[u][i].aq)]; 79 else 80 ans[num[u][i]]=dis1[query[u][i].aq]+dis2[u]-dis1[finds(query[u][i].aq)]-dis2[finds(query[u][i].aq)]; 81 // cout<<ans[num[u][i]]<<query[u][i].aq<<" "<<dis2[query[u][i].aq]<<dis1[u]<<"####"<<endl; 82 } 83 } 84 } 85 int main(){ 86 int t; 87 scanf("%d",&t); 88 while(t--){ 89 int n; 90 cnt=0; 91 int sum=0; 92 scanf("%d",&n); 93 for(int i=1;i<=n;i++)head[i]=-1; 94 for(int i=1;i<=n-1;i++){ 95 int a,b,c,d; 96 scanf("%d%d%d%d",&a,&b,&c,&d); 97 adde(a,b,d,c); 98 adde(b,a,c,d); 99 sum+=c+d; 100 } 101 init(n); 102 int q; 103 scanf("%d",&q); 104 for(int i=1;i<=q;i++){ 105 int a,b; 106 scanf("%d%d",&a,&b); 107 struct pot aa; 108 aa.aq=b; 109 aa.xzc=0; 110 query[a].push_back(aa); 111 struct pot bb; 112 bb.aq=a; 113 bb.xzc=1; 114 query[b].push_back(bb); 115 num[a].push_back(i); 116 num[b].push_back(i); 117 } 118 Tarjan(1,0,0); 119 for(int i=1;i<=q;i++){ 120 printf("%d ",sum-ans[i]); 121 } 122 123 124 } 125 return 0; 126 }