Time Limit: | 4000/2000 MS (Java/Others) | Memory Limit: | 131072/131072 K (Java/Others) |
---|
Recently, Peter saw the equation x0+2x1+4x2+...+2mxm=n . He wants to find a solution ( x0,x1,x2,...,xm ) in such a manner that ∑mi=0xi is minimum and every x i (0≤i≤m) is non-negative.
There are multiple test cases. The first line of input contains an integer T (1≤T≤10 5 ), indicating the number of test cases. For each test case:
The first contains two integers n and m (0≤n,m≤ 109 ).
For each test case, output the minimum value of ∑mi=0xi .
10
1 2
3 2
5 2
10 2
10 3
10 4
13 5
20 4
11 11
12 3
1
2
2
3
2
2
3
2
3
2
水题:将n分解成二级制,如果m小于n的位数,将剩余的加在最高位就行
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
int n,m;
int Get(LL s)
{
int ans = 0;
int num = 0;
while(s&&num<m)
{
if(s%2) ans++;
num++;
s>>=1;
}
return ans+s;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
int ans = Get(n);
printf("%d\n",ans);
}
return 0;
}
Time Limit: | 6000/3000 MS (Java/Others) | Memory Limit: | 131072/131072 K (Java/Others) |
---|
Peter has a sequence a1,a2,...,an and he define a function on the sequence – F( a1,a2,...,an )=( f1,f2,...,fn ), where fi is the length of the longest increasing subsequence ending with ai .
Peter would like to find another sequence b1,b2,...,bn in such a manner that F( a1,a2,...,an ) equals to F( b1,b2,...,bn ). Among all the possible sequences consisting of only positive integers, Peter wants the lexicographically smallest one.
The sequence a1,a2,...,an is lexicographically smaller than sequence b1,b2,...,bn , if there is such number i from 1 to n, that ak=bk for 1≤k < i and ai<bi .
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first contains an integer n (1≤n≤100000) – the length of the sequence. The second line contains n integers a1,a2,...,an (1≤ ai ≤109).
For each test case, output n integers b1,b2,...,bn(1≤bi≤109) denoting the lexicographically smallest sequence.
3
1
10
5
5 4 3 2 1
3
1 3 5
1
1 1 1 1 1
1 2 3
F(f1,f2,...,fn)=F(a1,a2,...,an ), 显然这个是字典序最小的, 于是要求的序列就是 f1,f2,...,fn .用nlogn的时间复杂度。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=110000;
int n,val[N],a[N];
int len,arr[N];
int an[N];
int lowbit(int x)
{
return x&(-x);
}
void update(int i,int x)
{
while(x<=len)
{
if(i>arr[x])
arr[x]=i;
x+=lowbit(x);
}
}
int query(int x)
{
int ans=0;
while(x)
{
if(arr[x]>ans)
ans=arr[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%d",&val[i]);
a[i]=val[i];
}
sort(a,a+n);
len=unique(a,a+n)-a;
memset(arr,0,sizeof(arr));
int tmp;
for(int i=0; i<n; i++)
{
val[i]=lower_bound(a,a+len,val[i])-a+1;
tmp=query(val[i]-1)+1;
update(tmp,val[i]);
an[i] = tmp;
}
for(int i = 0;i<n;i++)
{
if(i) printf(" ");
printf("%d",an[i]);
}
printf("\n");
}
return 0;
}
Time Limit: | 10000/5000 MS (Java/Others) | Memory Limit: | 131072/131072 K (Java/Others) |
---|
Peter has an n×m matrix M. Let S(a,b) be the sum of the weight all a×b submatrices of M. The weight of matrix is the sum of the value of all the saddle points in the matrix. A saddle point of a matrix is an element which is both the only largest element in its column and the only smallest element in its row. Help Peter find out all the value of S(a,b).
Note: the definition of saddle point in this problem may be different with the definition you knew before.
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first contains two integers n and m (1≤n,m≤1000) – the dimensions of the matrix.
The next n lines each contain m non-negative integers separated by spaces describing rows of matrix M (each element of M is no greater than 106).
For each test case, output an integer W=(∑a=1n∑b=1ma⋅b⋅S(a,b)) mod 232 .
3
2 2
1 1
1 1
3 3
1 2 3
4 5 6
7 8 9
3 3
1 2 1
2 3 1
4 5 2
4
600
215
题意:给你一个矩阵,计算所有子矩阵矩阵的值的,既矩阵的面积与鞍点的乘积。考虑每一个鞍点的贡献,假设我们已经知道某个鞍点的的上下左右的有效区间,那么我们可以得出
ans =∑i=0a∑j=0b∑s=0c∑k=0d(i+j+1)×(s+k+1)=∑i=0a∑j=0b(i+j+1)×∑s=0c∑k=0d(s+k+1)=[∑i=0a[(b+1)i]+(a+1)∑j=0b(j+1)]×[∑s=0c[s(d+1)]+(c+1)∑k=0d(k+1)=[(b+1)(a+1)a2+×(b+2)(b+1)(a+1)2]×[(d+1)(c+1)c2+(d+2)(d+1)(c+1)2]=(a+1)(b+1)(b+a+2)2×(c+1)(d+1)(c+d+2)2
我们可以用单调队列处理出每个鞍点在行和列的上下限,然后进行处理。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
const int Max = 1100;
void read(int &ans)
{
char ch;
while((ch = getchar())<'0' && ch >'9');
ans = ch-'0';
while((ch = getchar())>='0' && ch<='9')
{
ans = ans*10+ch-'0';
}
}
int n,m;
int arr[Max][Max];
int st[Max];
int L[Max][Max],R[Max][Max],up[Max][Max],dn[Max][Max];
unsigned cal(unsigned a,unsigned b,unsigned c,unsigned d)
{
return ((a+1)*(b+1)*(a+b+2)/2)*((c+1)*(d+1)*(c+d+2)/2);
}
int main()
{
int T;
read(T);
while(T--)
{
read(n); read(m);
for(int i = 1;i<=n;i++)
{
for(int j = 1;j<=m;j++)
{
read(arr[i][j]);
L[i][j] = 1;
R[i][j] = m;
up[i][j] = 1;
dn[i][j] = n;
}
}
int top;
for(int i = 1;i<=n;i++)
{
top = 0;
st[++top] = 0;
for(int j = 1;j<=m;j++)
{
while(top>1 && arr[i][st[top]] > arr[i][j])
{
R[i][st[top]] = min(j-1,R[i][st[top]]);
top--;
}
if(top>1 && arr[i][st[top]] == arr[i][j]) L[i][j] = max(L[i][j],st[top]+1) ;
while(top>1 && arr[i][st[top]] == arr[i][j])
{
R[i][st[top]] = min(j-1,R[i][st[top]]);
top --;
}
L[i][j] = max(L[i][j],st[top]+1);
st[++top] = j;
}
}
for(int i = 1;i<=m;i++)
{
top = 0;
st[++top] = 0;
for(int j = 1;j<=n;j++)
{
while(top>1 && arr[st[top]][i]< arr[j][i])
{
dn[st[top]][i] = min(j-1,dn[st[top]][i]);
top--;
}
if(top >1 && arr[st[top]][i] == arr[j][i]) up[j][i] =max(up[j][i],st[top]+1);
while(top>1 && arr[st[top]][i] == arr[j][i])
{
dn[st[top]][i] = min(j-1,dn[st[top]][i]);
top--;
}
up[j][i] = max(up[j][i],st[top]+1);
st[++top] = j;
}
}
unsigned int ans = 0;
for(int i = 1;i<=n;i++)
{
for(int j = 1;j<=m;j++)
{
unsigned c1 = j - L[i][j];
unsigned c2 = R[i][j]-j;
unsigned h1 = i - up[i][j];
unsigned h2 = dn[i][j] - i;
unsigned s = arr[i][j];
ans +=cal(c1,c2,h1,h2)*s;
}
}
cout<<ans<<endl;
}
return 0;
}
Time Limit: | 7000/3500 MS (Java/Others) | Memory Limit: | 131072/131072 K (Java/Others) |
---|
A positive proper divisor is a positive divisor of a number n, excluding n itself. For example, 1, 2, and 3 are positive proper divisors of 6, but 6 itself is not.
Peter has two positive integers n and d. He would like to know the number of integers below n whose maximum positive proper divisor is d.
There are multiple test cases. The first line of input contains an integer T (1≤T≤ 106 ), indicating the number of test cases. For each test case:
The first line contains two integers n and d (2≤n,d≤ 109 ).
For each test case, output an integer denoting the answer.
9
10 2
10 3
10 4
10 5
10 6
10 7
10 8
10 9
100 13
1
2
1
0
0
0
0
0
4
比赛的时候手残,最后T了。问小于n的数中有多少个数的最大的因子是d,显然的事是d一定和素数相乘,并且小于等于min( n−1d,d ),但是当d不是素数的时候,我们找到d的最小质因子s,那么ans就是小于等于min( n−1d,d,s )的素数的个数。
#include<iostream>
#include<cstdio>
#include<cstring>
#include <cmath>
#include<algorithm>
using namespace std;
const int Max = 1e7+100;
int prime[Max];
int vis[Max];
int num[Max];
void Get()
{
prime[0] =0 ;
num[0] = num[1] = 0;
for(int i = 2; i<Max; i++)
{
if(!vis[i])
{
prime[++prime[0]] = i;
for(int j =i+i; j<Max; j+=i)
{
if(!vis[j]) vis[j] = i;
}
}
num[i] = num[i-1];
if(!vis[i]) num[i]++;
}
}
int n,p;
int main()
{
Get();
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&p);
int s=(n-1)/p;
if(s <= 1)
{
printf("0\n");
continue;
}
int ans = 0;
for(int i = 1;i<=prime[0] && prime[i]<=s;i++)
{
ans++;
if(p%prime[i] == 0)
{
break;
}
}
printf("%d\n",ans);
}
return 0;
}