1. 程式人生 > 實用技巧 >uiautomator2+python 子元素遍歷

uiautomator2+python 子元素遍歷

一種優雅的暴力演算法

mind:

分塊

離散化

通過合理地對詢問排序,然後以較優的順序暴力回答每個詢問(兩個指標左右擴張或縮小範圍)

借題理解

[https://www.luogu.com.cn/problem/P3901](Luogu P3901 數列找不同)

莫隊發展里程

1.首先這個題很明顯可以暴力跑,然後開個桶記錄一下(慢到家

2.珂以在區間[1,5]的基礎上,去掉位置1(即將左端點右移一位),加上位置6(即將右端點右移一位),得到區間[2,6]的答案
對於[99999,100000]這樣的鬼畜資料肯定會被卡

所以就莫隊就從此把分塊納了進去,先對資料進行了排序,然後在由上述操作鎖定區間

怎樣排序捏??

莫隊提供了這樣一個排序方案:將原序列以n1/2

為一塊進行分塊(分塊的大小也珂以調整),排序第一關鍵字是詢問的左端點所在塊的編號,第二關鍵字是詢問的右端點本身的位置,都是升序。然後我們用上面提到的“移動當前區間左右端點”的方法,按順序求每個詢問區間的答案,移動每一個詢問區間左右端點可以求出下一個區間的答案

莫隊排序程式碼:


bool cmp(Query a,Query b)
{ 
    return a.bl==b.bl?a.r<b.r:a.bl<b.bl;
}

但由於出題人過於狠毒
又多出一種優化,叫做奇偶優化
按奇偶塊排序。這也是比較通用的。如果區間左端點所在塊不同,那麼就直接按左端點從小到大排;如果相同,奇塊按右端點從小到大排,偶塊按右端點從大到小排

程式碼如下


 bool cmp(Query a,Query b)
{
    return a.bl!=b.bl?a.l<b.l:((a.bl&1)?a.r<b.r:a.r>b.r);
}

莫隊核心程式碼


 sort(q + 1,q + m + 1, cmp);
   for(int i = 1;i <= m; i++){
   	  L = q[i].l,R = q[i].r;
   	  while(nl < L) del(nl++);
	  while(nl > L) add(--nl);
	  while(nr < R) add(++nr);
	  while(nr > R) del(nr--);
	  if(ans == (R - L + 1)){
	  	  ANS[q[i].num] = 1;
	  }  
   }

正式程式碼

複雜度
O(n*n1/2)

/*
work by:Ariel_
*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define N 100010
using namespace std;
typedef long long ll;
int read(){
	int x = 0,f = 1;char c = getchar();
	while(c < '0'||c > '9'){
	if(c == '-')f = -1;c = getchar();}
	while(c >= '0'&& c <= '9'){x = x*10 + c - '0',c = getchar();}
	return x*f;
}
int n,m,lucky_block,L,R,a[N],nl,nr,ANS[N],ans,cnt[N]; 
struct Query{
	int l, r , num;
}q[N];
bool cmp(Query a,Query b){
    return (a.l/lucky_block) == (b.l/lucky_block) ? a.r < b.r : a.l < b.l;//排序 
}
void add(int pos){
	if(++cnt[a[pos]] == 1) ans++;
}
void del(int pos){
	if(--cnt[a[pos]] == 0) ans--;
}
int main(){
   n = read(),m = read();
   lucky_block = sqrt(n);
   for(int i = 1;i <= n; i++){
   	    a[i] = read();
   }
   for(int i = 1; i <= m; i++){
   	   q[i].l = read();
   	   q[i].r = read();
   	   q[i].num = i;
   } 
   sort(q + 1,q + m + 1, cmp);
   
   for(int i = 1;i <= m; i++){
   	  L = q[i].l,R = q[i].r;
   	  while(nl < L) del(nl++);
	  while(nl > L) add(--nl);
	  while(nr < R) add(++nr);
	  while(nr > R) del(nr--);
	  if(ans == (R - L + 1)){
	  	  ANS[q[i].num] = 1;
	  }  
   }
   for(int i = 1;i <= m; i++){
   	   if(ANS[i] == 1){
   	     printf("Yes\n");	
	   }
	   else{
	   	  printf("No\n");
	   }
   } 
}