题解:CF1690G Count the Trains

  1. 思路: 首先我们可以理清一下各种情况:

    1)m可能为0

    2)一次操作时,只需要考虑每节火车的车头。

    3)当一节火车的速度降低时,只会影响它及它后面的车厢

    当m=0时,我们可以记录上一节车头的速度从而O(n) 解决问题

    同理,一节车厢会不会成为车头取决于上一节车头的速度,也就是前面车厢的状态不会改变。 当车厢 k 操作时,首先向后遍历车头 x;

    • 如果 ax≥ak-d,那么x 将不再是车头。

    然后比较新车厢和这节车厢前的第一个车头y

    • 若ay≥ak-d,那么ak就是新的车头

    我们可以发现能用set做,时间复杂度为O(nlogn) 

  2. 代码:

    #include
    using namespace std;
    const int N=1e5+10;
    int t,a[N];
    int main(){
        scanf("%d",&t);
        while(t--){
    	    int n,m;
            scanf("%d%d",&n,&m);
    	    	set s;
            for(int i = 1;i <= n;i ++){
            	scanf("%d",&a[i]);
            	if(!s.size()||a[i]=x) {
                	s.erase(*s.lower_bound(k));
    		    }
                if(s.lower_bound(k)==s.begin()||a[*(--s.lower_bound(k))]>x){
    		    	s.insert(k);
    		    }
                a[k]-=d;
                printf("%d ",s.size());
            }
    	    printf("\n");
        }
    }

你可能感兴趣的:(CF,算法,c++,数据结构)