A - Buildings
找出n个大楼里比最左边大楼高(严格大于)的最左边的楼,如果没有输出-1;
边输入边找,暴力直接过;
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int a,b,c,d,n,m,l,t,ans=0,sum=0;
int v[20005];
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
int sign=0;
cin>>a;
for(int i=1;i<n;i++){
cin>>b;
if(b>a){
cout<<i+1;
sign=1;
break;
}
}
if(sign==0){
cout<<-1;
}
return 0;
}
B - AtCoder Amusement Park
有n个团体要坐船,每个船能坐m个人,每个团体里的人必须在一艘船上,一艘船可以同时坐多个团体,给出V1,V2..VI..Vn为按上船顺序的团体成员数,求最少需要几艘船;
暴力上船,人多了就换下艘,用l来记录当前船只的空位即可;
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int a,b,c,d,n,m,l,t,ans=0,sum=0;
int v[20005];
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>m;
ans=0;
l=0;
for(int i=0;i<n;i++){
cin>>a;
if(l<a){
ans++;
l=m-a;
}
else{
l=l-a;
}
}
cout<<ans;
return 0;
}
C - Sigma Problem
设 f ( x , y ) = ( x + y )%1e8 ,给出n个数,求所有数对 f ( Ai , Aj ) (1<=i<j<=n) 的和;
2≤N≤3×105,1≤Ai<1e8
相加对1e8取余就相当于加起来大于1e8的话再减掉1e8,所有数对相加也是这样;
所以只需要把所有数对的原始和求出来,再减掉成功取余的次数k*1e8就可以了
因为Ai小于1e8,所以每一次f(x,y)最多只能减1次1e8,不需要对取余求整除;
求成功次数,先从小到大排序,再用双指针头尾往中间走就好
#include<bits/stdc++.h>
using namespace std;
#define ll long long
long long int a,b,c,d,n,m,l,t,ans=0,sum=0;
int v[300005];
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int p=100000000;
cin>>n;
for(int i=0;i<n;i++){
cin>>v[i];
sum+=v[i];
}
sum*=n-1;
sort(v,v+n);
a=0,b=n-1;
while(a<b){
if(v[a]+v[b]<p){
a++;
}
else{
ans+=b-a;
b--;
}
}
sum-=ans*p;
cout<<sum;
return 0;
}
D - Another Sigma Problem
和上题一样,f ( x , y ) 的定义被改为了字符串加法
求所有数对 f ( Ai , Aj ) (1<=i<j<=n) 的和 结果mod998244353;
如f(3,14)=314 , f(3,15)=315 , f(14,15)=1415;
因为i<j,所以对于Aj所有的f(Ai,Aj)都相当于数列中前面的数乘上p(p=10的k次方(k=自己的位数))再加上自己,所以对每个Aj要给ans=ans +Aj-1的前缀和*p+Aj*(j-1);
由于数据量庞大,所以在许多地方需要对998244353取余,不然会爆longlong,我就是在这点上卡了还送了3个罚时;
#include<bits/stdc++.h>
using namespace std;
#define ll long long
long long int a,b,c,d,n,m,l,t,ans=0,sum=0;
long long int v[200005];
long long int z[200005];
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=0;i<n;i++){
z[i]=1;
cin>>v[i];
ans=(ans+v[i]*i)%998244353;
a=v[i];
while(a>0){
a/=10;
z[i]*=10;
}
ans=(ans+(z[i]%998244353)*(sum%998244353))%998244353;
sum=sum+v[i];
}
cout<<ans;
return 0;
}
E - Yet Another Sigma Problem
还是同上Ai变成了字符串且 f ( Ai , Aj )的定义变成了公共前缀的长度;
求所有 f ( Ai , Aj ) (1<=i<j<=n) 的和;
- 2≤N≤3×105
- ∣S1∣+∣S2∣+…+∣Sn∣≤3×105
求多字符串的公共前缀,采用字典树,把每个字符串从首字母开始单字母地打入树,如果此层有来过就记录+1,没字符串来过就开新节点,这样每次新字符串导入的时候都能查看到前面字符串与其的公共点总和;
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct node{
node *next[26];
int data;
node(){
for(int i=0;i<26;i++){
next[i]=NULL;
}
data=0;
}
};
long long int a,b,c,d,n,m,l,t,ans=0,sum=0;
string s;
node *find(node *head){
node* now=head;
for(int i=0;i<s.length();i++){
int a=s[i]-'a';
if(now->next[a]==NULL){
now->next[a]=new node;
}
ans+=now->next[a]->data;
now->next[a]->data++;
now=now->next[a];
}
return head;
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
node *head=new node;
cin>>n;
for(int i=0;i<n;i++){
cin>>s;
head=find(head);
}
cout<<ans;
return 0;
}