C~F Java题解,代码已去除冗余~~~
按照列存储每一列空白位置,操作1的时候种植并清空,操作的2的时候把位置加入,时间复杂度O(mn+k)
import java.util.*;
public class Main{
static long seed;
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt(),m=sc.nextInt(),k=sc.nextInt();
seed=sc.nextLong();
List<Integer> list[]=new List[m+5];
for(int i=1;i<=m;i++){
list[i]=new ArrayList<>();
for(int j=1;j<=n;j++){
list[i].add(j);
}
}
long arr[][]=new long[n+5][m+5],ans=0;
for(int i=0;i<k;i++){
long op=rnd()%2+1;
if(op==1){
long idx=rnd()%m+1,x=rnd()%(n*m)+1;
for(int a:list[(int)idx]){
arr[a][(int)idx]=x;
}
list[(int)idx].clear();
}
else{
int a=(int)(rnd()%n+1),b=(int)(rnd()%m+1);
if(arr[a][b]!=0){
list[b].add(a);
arr[a][b]=0;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
ans^=arr[i][j]*((i-1)*m+j);
}
}
System.out.println(ans);
}
static long rnd(){
long p=1L<<32,ret=seed;
seed=(seed^((seed<<13)%p))%p;
seed=(seed^((seed>>17)%p))%p;
seed=(seed^((seed<<5)%p))%p;
return ret;
}
}
相邻的字符串p要么是取自同一个字串,要么是向右的平移一个单位的字串,而后者成立的条件只能是字串仅有一种字母构成,因此对任意k,操作即为将同种字母缩短为最多k连续,时间复杂度O(nlogn)
import java.util.*;
public class Main{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt(),sum=n,count=0;
long ans=0;
String s=sc.next();
Queue<Integer> q=new PriorityQueue<>((a,b)->b-a);
for(int i=0,j=0;i<n;){
while(j<n&&s.charAt(i)==s.charAt(j)){
j++;
}
q.add(j-i);
i=j;
}
for(int i=n;i>0;i--){
while(!q.isEmpty()&&q.peek()>=i){
sum-=q.poll();
count++;
}
ans^=(long)i*(sum+i*count);
}
System.out.println(ans);
}
}
对于权值较小的点,尽量用更多的连接其他点,只需要找到前n-1可以的连的边就是理论上的最小边权和,时间复杂度O(nlogn)
import java.util.*;
public class Main{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt(),a[]=new int[n],d[]=new int[n];
long ans=0;
Queue<Integer> q=new PriorityQueue<>((p1,p2)->Integer.compare(a[p1],a[p2]));
for(int i=0;i<n;i++){
a[i]=sc.nextInt();
q.add(i);
}
for(int i=0;i<n;i++){
d[i]=sc.nextInt();
}
for(int i=0;i<n-1;i++){
int b=q.poll();
ans+=a[b];
d[b]--;
if(d[b]>0){
q.add(b);
}
}
System.out.println(ans);
}
}
参考资料。。。。待完善,时间复杂度O(n)
import java.util.*;
public class Main{
static long seed;
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt(),k=sc.nextInt(),idx[]=new int[n+5],len[]=new int[n+5],ans=0;
seed=sc.nextLong();
for(int i=1;i<=k;i++){
int a=(int)(rnd()%n+1);
if(idx[a]==0){
idx[a]=i;
}
}
Stack<Integer> stack=new Stack<>();
for(int i=1;i<=n;i++){
if(idx[i]>0){
while(!stack.isEmpty()&&stack.peek()>idx[i]){
stack.pop();
}
stack.push(idx[i]);
}
else{
len[i]=stack.size();
}
}
stack.clear();
for(int i=n;i>0;i--){
if(idx[i]>0){
while(!stack.isEmpty()&&stack.peek()>idx[i]){
stack.pop();
}
stack.push(idx[i]);
}
else{
len[i]+=stack.size();
}
}
for(int i=1;i<=n;i++){
if(idx[i]==0&&(ans==0||len[i]<len[ans])){
ans=i;
}
}
System.out.println(ans);
}
static long rnd(){
long p=1L<<32,ret=seed;
seed=(seed^((seed<<13)%p))%p;
seed=(seed^((seed>>17)%p))%p;
seed=(seed^((seed<<5)%p))%p;
return ret;
}
}