A. Little Artem and Matrix
没什么好说的,逆向模拟一下。
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define ll long long
int a[10010][5];
int ans[111][111];
int main(){
int n,m,q;
cin>>n>>m>>q;
for(int i=1;i<=q;i++){
scanf("%d",&a[i][0]);
if(a[i][0]==3){
for(int j=1;j<=3;j++){
scanf("%d",&a[i][j]);
}
}else{
scanf("%d",&a[i][1]);
}
}
for(int i=q;i>0;i--){
if(a[i][0]==1){
int tmp = ans[ a[i][1] ][m];
for(int j=m;j>1;j--){
ans[ a[i][1] ][j] = ans[ a[i][1] ][j-1];
}
ans[ a[i][1] ][1] = tmp;
}else if(a[i][0]==2){
int tmp = ans[ n ][a[i][1]];
for(int j=n;j>1;j--){
ans[ j ][a[i][1]] = ans[j-1][ a[i][1] ];
}
ans[1][ a[i][1] ] = tmp;
}else if(a[i][0]==3){
ans[a[i][1]][a[i][2]] = a[i][3];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<ans[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
B. Little Artem and Dance
其实分析一下就能发现,奇数的相对位置是不会变的,偶数的也是。所以一个简单的做法就是维护1和2的位置。
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define ll long long
int ans[1000010];
int main(){
int n,q;
cin>>n>>q;
int one = 1;
int two = 2;
for(int i=1;i<=q;i++){
int op;
scanf("%d",&op);
if(op==1){
int x;
scanf("%d",&x);
one+=x;
two+=x;
}else{
if(one&1){
one++;
}else{
one--;
}
if(two&1){
two++;
}else{
two--;
}
}
while(one>n){
one-=n;
}
while(one<1){
one+=n;
}
while(two>n){
two-=n;
}
while(two<1){
two+=n;
}
}
for(int i=1;i<=n;i+=2){
ans[one]=i;
one+=2;
if(one>n){
one-=n;
}
}
for(int i=2;i<=n;i+=2){
ans[two]=i;
two+=2;
if(two>n){
two-=n;
}
}
for(int i=1;i<=n;i++){
printf("%d ",ans[i]);
}
return 0;
}
C. Little Artem and Random Variable
大坑!C居然比D难,差一点码完,巨亏。。
我们按顺序推两个骰子的每个点的概率即可。根据max和min的分布,可以推出一个一元二次方程,化简然后解之可以得到每个点的概率。。
这个题我跪了一发,跪在二次方程判别式出现了一个极小的负数。。
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define ll long long
double ansA[100010];
double ansB[100010];
double delta;
double x1,x2;
// ax^2 + bx + c = 0
void solve(double a,double b,double c){
double d=b*b-4*a*c;
delta = d;
if(d<=0){
x1=x2=(-b)/(2*a);
}else{
double e=sqrt(d);
x1=(-b+e)/(2*a);
x2=(-b-e)/(2*a);
}
}
double MIN[100010];
double MAX[100010];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
scanf("%lf",&MAX[i]);
}
for(int i=1;i<=n;i++){
scanf("%lf",&MIN[i]);
}
double suma=0;
double sumb=0;
for(int i=1;i<=n;i++){
// ansA[i] + ansB[i] = MIN[i] + MAX[i]
// sumb*ansA[i] +suma*ansB[i] + ansA[i]*ansB[i] = MAX[i]
//
double minSum = min(suma,sumb);
// let x = ansA[i]
double sum = MIN[i] + MAX[i];
double a = -1.0;
double b = sumb - suma + sum;
double c = suma*sum - MAX[i] ;
solve(a,b,c);
x2 = sum-x1;
ansA[i] = x1;
ansB[i] = x2;
suma += x1;
sumb += x2;
}
for(int i=1;i<=n;i++){
cout<<ansA[i]<<" ";
}
cout<<endl;
for(int i=1;i<=n;i++){
cout<<ansB[i]<<" ";
}
return 0;
}
D. Little Artem and Time Machine
又是喜闻乐见的数据结构题。。这个题并不需要什么高端的姿势,大家常见的数据结构就能解决。首先,对不同的数的操作其实是独立的,可以分开处理。对于每个操作数,把操作时间离散化,用BIT维护对它进行增加,删除的时间,再根据查询操作的时间点查询一下在这之前被增加/删除了多少次,增加次数减去删除次数就是答案。。
#include <bits/stdc++.h>
using namespace std;
struct operation{
int op;
int time;
int x;
int id;
bool operator<(const operation &other)const{
if(x!=other.x){
return x<other.x;
}
return id<other.id;
}
}ops[100010];
int ca[100010];
int cr[100010];
int lowbit(int x){
return x&(-x);
}
int sz;
void updatea(int x){
while(x<=sz){
ca[x]++;
x+=lowbit(x);
}
}
int querya(int x){
int res = 0;
while(x){
res+=ca[x];
x-=lowbit(x);
}
return res;
}
void updater(int x){
while(x<=sz){
cr[x]++;
x+=lowbit(x);
}
}
int queryr(int x){
int res = 0;
while(x){
res+=cr[x];
x-=lowbit(x);
}
return res;
}
int res[100010];
int main(){
memset(res,-1,sizeof(res));
int n;
cin>>n;
for(int i=0;i<n;i++){
scanf("%d%d%d",&ops[i].op,&ops[i].time,&ops[i].x);
ops[i].id = i;
}
sort(ops,ops+n);
for(int i=0;i<n;i++){
int end = i;
while(ops[end].x==ops[end+1].x && end<n-1){
end++;
}
map<int,int> mp;
for(int j=i;j<=end;j++){
mp[ops[j].time];
}
int k = 1;
for(auto it = mp.begin();it!=mp.end();it++){
it->second = k++;
}
sz = end-i+2;
for(int j=0;j<=sz;j++){
ca[j] = cr[j] = 0;
}
for(int j=i;j<=end;j++){
int mpTime = mp[ops[j].time];
if(ops[j].op==1){
updatea(mpTime);
}else if(ops[j].op==2){
updater(mpTime);
}else{
int ans = querya(mpTime) - queryr(mpTime);
res[ops[j].id] = ans;
}
}
i = end;
}
for(int i=0;i<n;i++){
if(res[i]!=-1){
printf("%d\n",res[i]);
}
}
return 0;
}