A. Lily
思路:简单的签到,所有不在 L 旁的字符替换为 C 即可。
代码:(以及注意注释里的部分) 是谁签到题都WA呀 哦是我呀.jpg
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;cin>>n;
string s;cin>>s;
for(int i=0;i<n;i++)if(s[i]=='.')s[i]='C';
for(int i=0;i<n;i++){
if(s[i]=='L'){//注意这里L的判断
if(i!=0&&s[i-1]=='C')s[i-1]='.';//注意这里C的判断
if(i!=n-1&&s[i+1]=='C')s[i+1]='.';
}
}
cout<<s;
return 0;
}
M. Youth Finale
提交的结果(题目限制3s)
2230 ms | 11900 KB |
思路:
冒泡排序求要交换的次数=求逆序对个数
所以可以用归并排序或树状数组求逆序对O(nlogn)
之后输入m个操作,求执行该操作后的逆序对个数
为了记录每一次的操作后数组的状态,用了stl的list来记录
对于reverse操作,新逆序对个数=组合数nC2-旧逆序对个数
对于swap操作,设交换了y,新逆序对个数=(n-y)-(y-1)=n-2y+1
务必记得开long long
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[300005],base[300005];
int ans=0,l,r;
void mergesort(int l,int r)//归并排序
{
if(l==r) return;
int mid=(l+r)>>1;
if(l<=mid) mergesort(l,mid); //左递归
if(mid+1<=r) mergesort(mid+1,r);//右递归
int ln=l,rn=mid+1,k=l; //合并操作
while(ln<=mid&&rn<=r){
if(base[ln]<base[rn]) a[k++]=base[ln++];
else{
a[k++]=base[rn++];
ans+=mid-ln+1;
}
}
while(ln<=mid) a[k++]=base[ln++];
while(rn<=r) a[k++]=base[rn++];
for(int i=l;i<=r;i++){
base[i]=a[i];
}
}
signed main() //务必记得开long long
{
list<int> li; //因为给了3秒 最终耗时2230 ms
int n,m;cin>>n>>m;
int zu=n*(n-1)/2;
for(int i=1;i<=n;i++){cin>>base[i];li.push_back(base[i]);}
mergesort(1,n);//交换次数就是在求逆序对
cout<<ans<<'\n';char x;
for(int i=0;i<m;i++){
cin>>x;
if(x=='R'){reverse(li.begin(),li.end());ans=zu-ans;cout<<ans%10;}
else{
int y=*li.begin();
li.erase(li.begin());
li.push_back(y);
ans+=(n-y);
ans-=(y-1);
cout<<ans%10;
}
}
}
C. Array Concatenation
思路:
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[100005];
int b[200005];//注意这里要开两倍,不然WA
const int mod=1000000007;
long long binpow(long long a, long long b, long long m) {
a %= m;
long long res = 1;
while (b > 0) {
if (b & 1) res =res * a % m;
a =a * a % m;
b >>= 1;
}
return res;
}
signed main()
{
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++){cin>>a[i];}
for(int i=1;i<=n;i++){b[i]=a[n-i+1];b[n+i]=a[i];}
int s=0,ss=0;
for(int i=1;i<=2*n;i++){
s=s+b[i];s=s%mod;
ss=ss+s;ss=ss%mod;
}
int ans1=(ss*binpow(2,m-1,mod)%mod+binpow(2,m-1,mod)*(binpow(2,m-1,mod)+mod-1)%mod*2*n%mod*s%mod*binpow(2,mod-2,mod)%mod)%mod;
s=0,ss=0;
for(int i=1;i<=n;i++){
s=s+a[i];s=s%mod;
ss=ss+s;ss=ss%mod;
}
int ans2=(ss*binpow(2,m,mod)%mod+binpow(2,m,mod)*(binpow(2,m,mod)+mod-1)%mod*n%mod*s%mod*binpow(2,mod-2,mod)%mod)%mod;
cout<<max(ans2,ans1)<<endl;
return 0;
}
E. Draw a triangle
思路(官方题解):
注意:
1.向量不要写反,A(x1,y1)B(x2,y2)AB(x2-x1,y2-y1)
2.叉积不要写反,注意exgcd为 exgcd(-b,a,x,y);
3.遇到x1=x2 or y1=y2 要注意判断
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int exgcd(int a, int b, int &x, int &y)
{
if(! b){x=1;y = 0;}
else{
exgcd(b, a % b, x, y);
int t=x;
x=y;y=t-(a/b)*y;
}
return 0;
}
signed main()
{
int T;cin>>T;
while(T--){
int x1,x2,y1,y2;
cin>>x1>>y1>>x2>>y2;
int a=(-x1+x2),b=(-y1+y2);
if(a==0){
cout<<x1+1<<" "<<y1<<'\n';
}
else if(b==0){
cout<<x1<<" "<<y1+1<<'\n';
}
else{
int x,y;
exgcd(-b,a,x,y);
cout<<x1+x<<" "<<y1+y<<'\n';
}
}
return 0;
}